Skip to content

Commit

Permalink
test: init e2e boilerplate (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidecarpini authored Nov 7, 2023
1 parent 0db1dda commit d46e204
Show file tree
Hide file tree
Showing 19 changed files with 843 additions and 41 deletions.
17 changes: 17 additions & 0 deletions apps/e2e/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const Config = require('@vechain/repo-config');

module.exports = {
...Config.EslintLibrary,
rules: {
'func-style': 'off',
'func-names': 'off',
'prefer-arrow-callback': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/naming-convention': 'off',
'@typescript-eslint/consistent-type-imports': 'off',
},
};
21 changes: 21 additions & 0 deletions apps/e2e/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Vechain

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
3 changes: 3 additions & 0 deletions apps/e2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
install playwright chromium drivers:

yarn playwright install
10 changes: 10 additions & 0 deletions apps/e2e/cucumber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
default: {
paths: ['./src/features/*.feature'],
require: ['./tests.setup.js', './src/**/*.ts'],
formatOptions: {
snippetInterface: 'synchronous',
},
publishQuiet: true,
},
};
18 changes: 18 additions & 0 deletions apps/e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "e2e",
"version": "1.0.0",
"license": "MIT",
"main": "index.js",
"scripts": {
"test": "cucumber-js",
"test:debug": "DEBUG=cucumber yarn test"
},
"devDependencies": {
"@cucumber/cucumber": "^8.10.0",
"@types/cucumber": "^7.0.0",
"@vechain/repo-config": "https://github.com/vechainfoundation/repo-config#v0.0.1",
"expect.js": "^0.3.1",
"playwright": "^1.39.0",
"ts-node": "^10.9.1"
}
}
9 changes: 9 additions & 0 deletions apps/e2e/src/features/connect-wallet.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Feature: The user can connect to a wallet

Background:
Given The user is in the homepage

Scenario Outline: The user can see every wallet option
When The user click the CTA to connect to a wallet
Then The user should see every wallet option

6 changes: 6 additions & 0 deletions apps/e2e/src/steps/common-steps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Given } from '@cucumber/cucumber';
import { ICustomWorld } from 'types';

Given('The user is in the homepage', async function (this: ICustomWorld) {
await this.openUrl('http://localhost:1234');
});
22 changes: 22 additions & 0 deletions apps/e2e/src/steps/connect-wallet-steps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Then, When } from '@cucumber/cucumber';
// eslint-disable-next-line import/no-extraneous-dependencies
import expect from 'expect';
import { ICustomWorld } from 'types';

When(
'The user click the CTA to connect to a wallet',
async function (this: ICustomWorld) {
await this.clickByText('Connect Wallet');
},
);

Then(
'The user should see every wallet option',
async function (this: ICustomWorld) {
expect(await this.isVisibleByText('Wallet Connect')).toBe(true);
expect(await this.isVisibleByText('VeWorld Extension')).toBe(true);
expect(await this.isVisibleByText('Sync')).toBe(true);
expect(await this.isVisibleByText('Sync 2')).toBe(true);
expect(await this.isVisibleByText('Sync 3')).toBe(false);
},
);
13 changes: 13 additions & 0 deletions apps/e2e/src/steps/custom-world.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { World, setWorldConstructor } from '@cucumber/cucumber';
import { ICustomWorld } from 'types';
import { openUrl, click, clickByText, isVisible, isVisibleByText } from 'utils';

export class CustomWorld extends World implements ICustomWorld {
openUrl = openUrl.bind(this);
click = click.bind(this);
clickByText = clickByText.bind(this);
isVisible = isVisible.bind(this);
isVisibleByText = isVisibleByText.bind(this);
}

setWorldConstructor(CustomWorld);
24 changes: 24 additions & 0 deletions apps/e2e/src/steps/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { ChromiumBrowser } from 'playwright';
import { chromium } from 'playwright';
import { After, AfterAll, Before, BeforeAll } from '@cucumber/cucumber';
import { ICustomWorld } from 'types';

let browser: ChromiumBrowser;

BeforeAll(async function () {
browser = await chromium.launch({ headless: false });
});

Before(async function (this: ICustomWorld) {
this.context = await browser.newContext();
this.page = await this.context.newPage();
});

After(async function (this: ICustomWorld) {
await this.page?.close();
await this.context?.close();
});

AfterAll(async function () {
await browser.close();
});
12 changes: 12 additions & 0 deletions apps/e2e/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { World } from '@cucumber/cucumber';
import { BrowserContext, Page } from 'playwright';

export interface ICustomWorld extends World {
context?: BrowserContext;
page?: Page;
openUrl: (url: string) => Promise<void>;
click: (selector: string) => Promise<void>;
clickByText: (text: string) => Promise<void>;
isVisible: (selector: string) => Promise<void>;
isVisibleByText: (text: string) => Promise<void>;
}
13 changes: 13 additions & 0 deletions apps/e2e/src/utils/browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import playwright from 'playwright';
import { ICustomWorld } from 'types';

async function openUrl(this: ICustomWorld, url: string) {
const browser = await playwright.chromium.launch({
headless: false,
});
const context = await browser.newContext();
this.page = await context.newPage();
await this.page.goto(url);
}

export { openUrl };
3 changes: 3 additions & 0 deletions apps/e2e/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './visibility';
export * from './browser';
export * from './mouse';
11 changes: 11 additions & 0 deletions apps/e2e/src/utils/mouse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ICustomWorld } from 'types';

async function click(this: ICustomWorld, selector: string) {
await this.page?.click(selector);
}

async function clickByText(this: ICustomWorld, text: string) {
await click.bind(this)(`text=${text}`);
}

export { click, clickByText };
11 changes: 11 additions & 0 deletions apps/e2e/src/utils/visibility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ICustomWorld } from 'types';

function isVisible(this: ICustomWorld, selector: string) {
return this.page?.locator(selector).first().isVisible();
}

function isVisibleByText(this: ICustomWorld, text: string) {
return isVisible.bind(this)(`text=${text}`);
}

export { isVisible, isVisibleByText };
8 changes: 8 additions & 0 deletions apps/e2e/tests.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require('ts-node').register({
transpileOnly: true,
require: ['tsconfig-paths/register'],
compilerOptions: {
module: 'commonjs',
baseUrl: 'src',
},
});
9 changes: 9 additions & 0 deletions apps/e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "@vechain/repo-config/src/tsconfig/react.json",
"compilerOptions": {
"noImplicitAny": false,
"noImplicitThis": false,
"baseUrl": "src"
},
"include": ["src"]
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"build-react-kit": "turbo run build --filter='@vechain/react-wallet-kit'",
"build:deps": "turbo build --no-daemon --filter='@vechain/*'",
"clean": "rm -rf .turbo .parcel-cache build && npx turbo@latest run clean",
"cucumber": "yarn && cucumber-js",
"dev": "turbo run dev --no-daemon",
"format": "prettier --write \"**/*.{ts,tsx,md,json,js,jsx}\"",
"install:all": "yarn && yarn run build:deps",
Expand Down
Loading

0 comments on commit d46e204

Please sign in to comment.