Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
chore: change eslint config to chainsafe shared (#152)
Browse files Browse the repository at this point in the history
* chore: change eslint to chainsafe config

* address PR comments

* address PR comments

* fix tests
  • Loading branch information
mpetrunic committed Dec 15, 2022
1 parent 3e73382 commit b19eeb9
Show file tree
Hide file tree
Showing 40 changed files with 1,417 additions and 1,158 deletions.
82 changes: 4 additions & 78 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,5 @@
require("@rushstack/eslint-patch/modern-module-resolution");

module.exports = {
root: true,
env: {
mocha: true,
node: true,
es6: true,
},
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'eslint-plugin-import', 'prettier'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
],
rules: {
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{
varsIgnorePattern: '^_',
},
],
'@typescript-eslint/explicit-function-return-type': [
'error',
{
allowExpressions: true,
},
],
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/explicit-module-boundary-types': 'error',
'@typescript-eslint/no-use-before-define': 'off',
'prefer-const': 'error',
'no-consecutive-blank-lines': 0,
'no-console': 'error',
'@typescript-eslint/naming-convention': [
'error',
{ selector: 'default', format: ['camelCase'] },
{
selector: ['classProperty', 'parameterProperty', 'objectLiteralProperty', 'classMethod', 'parameter'],
format: ['camelCase'],
leadingUnderscore: 'allow',
},
//variable must be in camel or upper case
{ selector: 'variable', format: ['camelCase', 'UPPER_CASE'], leadingUnderscore: 'allow' },
// {selector: "variable", modifiers: ["global"], format: ["PascalCase", "UPPER_CASE"]},
//classes and types must be in PascalCase
{ selector: ['typeLike', 'enum'], format: ['PascalCase'] },
{ selector: 'enumMember', format: null },
{ selector: 'typeProperty', format: ['PascalCase', 'camelCase'] },
//ignore rules on destructured params
{
selector: 'variable',
modifiers: ['destructured'],
format: null,
},
],
'import/order': [
'error',
{
groups: ['builtin', 'external', 'parent', 'internal', 'sibling'],
'newlines-between': 'always',
alphabetize: {
order: 'asc',
},
},
],
},
overrides: [
{
files: ['**/test/**/*.ts'],
rules: {
'no-console': 'off',
},
},
],
};
extends: "@chainsafe",
}
7 changes: 0 additions & 7 deletions .prettierrc.js

This file was deleted.

10 changes: 4 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,14 @@
"node-stream-zip": "^1.13.0"
},
"devDependencies": {
"@chainsafe/eslint-config": "^1.0.0",
"@jest/types": "^27.1.1",
"@rushstack/eslint-patch": "^1.2.0",
"@types/chai": "^4.2.22",
"@types/mocha": "^9.1.1",
"@typescript-eslint/eslint-plugin": "^4.15.0",
"@typescript-eslint/parser": "^4.15.0",
"@types/serve-handler": "^6.1.1",
"chai": "^4.3.4",
"eslint": "^7.20.0",
"eslint-config-prettier": "^7.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-prettier": "^3.3.1",
"eslint": "^8.24.0",
"ganache": "^7.4.3",
"jest-environment-node": "^27.1.1",
"mocha": "^10.0.0",
Expand Down
55 changes: 39 additions & 16 deletions src/helpers/actions.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,70 @@
import { Page } from 'puppeteer';
import { ElementHandle, Page } from "puppeteer";

import { getAccountMenuButton, getElementByContent, getInputByLabel, getSettingsSwitch } from './selectors';
import {
getAccountMenuButton,
getElementByContent,
getInputByLabel,
getSettingsSwitch,
} from "./selectors";

export const clickOnSettingsSwitch = async (page: Page, text: string): Promise<void> => {
export const clickOnSettingsSwitch = async (
page: Page,
text: string
): Promise<void> => {
const button = await getSettingsSwitch(page, text);
await button.click();
};

export const openNetworkDropdown = async (page: Page): Promise<void> => {
const networkSwitcher = await page.waitForSelector('.network-display', { visible: true });
const networkSwitcher = await page.waitForSelector(".network-display", {
visible: true,
});
try {
await networkSwitcher.click();
await page.waitForSelector('.network-dropdown-list', { visible: true, timeout: 1000 });
await page.waitForSelector(".network-dropdown-list", {
visible: true,
timeout: 1000,
});
} catch (e) {
//retry on fail
await networkSwitcher.click();
await page.waitForSelector('.network-dropdown-list', { visible: true, timeout: 1000 });
await page.waitForSelector(".network-dropdown-list", {
visible: true,
timeout: 1000,
});
}
};

export const openProfileDropdown = async (page: Page): Promise<void> => {
const accountSwitcher = await page.waitForSelector('.identicon');
const accountSwitcher = await page.waitForSelector(".identicon");
await accountSwitcher.click();
};

export const openAccountDropdown = async (page: Page): Promise<void> => {
const accMenu = await getAccountMenuButton(page);
await accMenu.click();
await page.waitForSelector('.menu__container.account-options-menu');
await page.waitForSelector(".menu__container.account-options-menu");
};

export const clickOnElement = async (page: Page, text: string, type?: string): Promise<void> => {
export const clickOnElement = async (
page: Page,
text: string,
type?: string
): Promise<void> => {
const element = await getElementByContent(page, text, type);
await element.click();
};

export const clickOnButton = async (page: Page, text: string): Promise<void> => {
const button = await getElementByContent(page, text, 'button');
export const clickOnButton = async (
page: Page,
text: string
): Promise<void> => {
const button = await getElementByContent(page, text, "button");
await button.click();
};

export const clickOnLogo = async (page: Page): Promise<void> => {
const header = await page.waitForSelector('.app-header__logo-container');
const header = await page.waitForSelector(".app-header__logo-container");
await header.click();
};

Expand All @@ -61,9 +84,9 @@ export const typeOnInputField = async (
text: string,
clear = false,
excludeSpan = false,
optional = false,
optional = false
): Promise<boolean> => {
let input;
let input: ElementHandle<HTMLInputElement>;
try {
input = await getInputByLabel(page, label, excludeSpan, 1000);
} catch (e) {
Expand All @@ -72,8 +95,8 @@ export const typeOnInputField = async (
}

if (clear)
await page.evaluate((node) => {
node.value = '';
await page.evaluate((node: HTMLInputElement) => {
node.value = "";
}, input);
await input.type(text);
return true;
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './actions';
export * from './selectors';
export * from "./actions";
export * from "./selectors";
39 changes: 26 additions & 13 deletions src/helpers/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { ElementHandle, Page } from 'puppeteer';
import { ElementHandle, Page } from "puppeteer";

// TODO: change text() with '.';
export const getElementByContent = (page: Page, text: string, type = '*'): Promise<ElementHandle | null> =>
page.waitForXPath(`//${type}[contains(text(), '${text}')]`, { timeout: 20000, visible: true });
export const getElementByContent = (
page: Page,
text: string,
type = "*"
): Promise<ElementHandle | null> =>
page.waitForXPath(`//${type}[contains(text(), '${text}')]`, {
timeout: 20000,
visible: true,
});

export const getInputByLabel = (
page: Page,
text: string,
excludeSpan = false,
timeout = 1000,
timeout = 1000
): Promise<ElementHandle> =>
page.waitForXPath(
[
Expand All @@ -22,30 +29,36 @@ export const getInputByLabel = (
`//span[contains(.,'${text}')]/following-sibling::*//input`,
]
: []),
].join('|'),
{ timeout, visible: true },
].join("|"),
{ timeout, visible: true }
);

export const getSettingsSwitch = (page: Page, text: string): Promise<ElementHandle | null> =>
export const getSettingsSwitch = (
page: Page,
text: string
): Promise<ElementHandle | null> =>
page.waitForXPath(
[
`//span[contains(.,'${text}')]/parent::div/following-sibling::div/div/div/div`,
`//span[contains(.,'${text}')]/parent::div/following-sibling::div/div/label/div`,
].join('|'),
{ visible: true },
].join("|"),
{ visible: true }
);

export const getErrorMessage = async (page: Page): Promise<string | false> => {
const options: Parameters<Page['waitForSelector']>[1] = { timeout: 1000 };
const options: Parameters<Page["waitForSelector"]>[1] = { timeout: 1000 };

const errorElement = await Promise.race([
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const errorElement: ElementHandle<HTMLElement> | null = await Promise.race([
page.waitForSelector(`span.error`, options),
page.waitForSelector(`.typography--color-error-1`, options),
page.waitForSelector(`.typography--color-error-default`, options),
]).catch(() => null);
if (!errorElement) return false;
return page.evaluate((node) => node.textContent, errorElement);
return page.evaluate((node: HTMLElement) => node.textContent, errorElement);
};

export const getAccountMenuButton = (page: Page): Promise<ElementHandle | null> =>
export const getAccountMenuButton = (
page: Page
): Promise<ElementHandle | null> =>
page.waitForXPath(`//button[contains(@title,'Account options')]`);
10 changes: 5 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// re-export
export { getMetaMask, getMetaMaskWindow } from './metamask';
export * from './types';
export * from './setup';
export { DappateerJestConfig } from './jest/global';
export { getMetaMask, getMetaMaskWindow } from "./metamask";
export * from "./types";
export * from "./setup";
export { DapeteerJestConfig as DappateerJestConfig } from "./jest/global";

// default constants
export const RECOMMENDED_METAMASK_VERSION = 'v10.20.0';
export const RECOMMENDED_METAMASK_VERSION = "v10.20.0";
11 changes: 6 additions & 5 deletions src/jest/DappeteerEnvironment.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import NodeEnvironment from 'jest-environment-node';
import puppeteer from 'puppeteer';
import { Config } from "@jest/types";
import NodeEnvironment from "jest-environment-node";
import puppeteer from "puppeteer";

import { getMetaMaskWindow } from '../index';
import { getMetaMaskWindow } from "../index";

class DappeteerEnvironment extends NodeEnvironment {
constructor(config) {
constructor(config: Config.ProjectConfig) {
super(config);
}

Expand All @@ -14,7 +15,7 @@ class DappeteerEnvironment extends NodeEnvironment {
// get the wsEndpoint
const wsEndpoint = process.env.PUPPETEER_WS_ENDPOINT;
if (!wsEndpoint) {
throw new Error('wsEndpoint not found');
throw new Error("wsEndpoint not found");
}

// connect to puppeteer
Expand Down
24 changes: 13 additions & 11 deletions src/jest/config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import path from 'path';
import path from "path";

import { existsSync } from 'node:fs';
import { cwd } from 'node:process';
import { existsSync } from "node:fs";
import { cwd } from "node:process";

import { RECOMMENDED_METAMASK_VERSION } from '../index';
import { LaunchOptions } from '../types';
import { RECOMMENDED_METAMASK_VERSION } from "../index";
import { LaunchOptions } from "../types";

import { DappateerJestConfig } from './global';
import { DapeteerJestConfig } from "./global";

export const DAPPETEER_DEFAULT_CONFIG: LaunchOptions = { metaMaskVersion: RECOMMENDED_METAMASK_VERSION };
export const DAPPETEER_DEFAULT_CONFIG: LaunchOptions = {
metaMaskVersion: RECOMMENDED_METAMASK_VERSION,
};

export async function getDappeteerConfig(): Promise<DappateerJestConfig> {
const configPath = 'dappeteer.config.js';
export async function getDappeteerConfig(): Promise<DapeteerJestConfig> {
const configPath = "dappeteer.config.js";
const filePath = path.resolve(cwd(), configPath);

if (!existsSync(filePath))
Expand All @@ -20,8 +22,8 @@ export async function getDappeteerConfig(): Promise<DappateerJestConfig> {
metaMask: {},
};

// eslint-disable-next-line @typescript-eslint/no-require-imports
const config = await require(filePath);
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment
const config: Partial<DapeteerJestConfig> = await require(filePath);

return {
dappeteer: {
Expand Down
6 changes: 3 additions & 3 deletions src/jest/global.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Browser, Page } from 'puppeteer';
import { Browser, Page } from "puppeteer";

import { Dappeteer, LaunchOptions, MetaMaskOptions } from '..';
import { Dappeteer, LaunchOptions, MetaMaskOptions } from "..";

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
Expand All @@ -13,7 +13,7 @@ declare global {
}
}

export type DappateerJestConfig = Partial<{
export type DapeteerJestConfig = Partial<{
dappeteer: LaunchOptions;
metaMask: MetaMaskOptions;
}>;
Loading

0 comments on commit b19eeb9

Please sign in to comment.