diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..5a3a08dfc --- /dev/null +++ b/.eslintrc @@ -0,0 +1,37 @@ +{ + "root": true, + "env": { + "node": true, + "mocha": true +}, + "parser": "@typescript-eslint/parser", + + "parserOptions": { + "ecmaVersion": 2017, + "sourceType": "module", + "project": ["./tsconfig.json"] // Specify it only for TypeScript files + +}, + "plugins": ["no-floating-promise","@typescript-eslint"], + "extends": [ + "plugin:wdio/recommended", + "plugin:@typescript-eslint/recommended", + "prettier/@typescript-eslint", + "plugin:prettier/recommended" +], + "rules": { + "@typescript-eslint/no-floating-promises": "error", + // RULES THAT NEED TO BE REMOVED + "class-methods-use-this": 0, + // //////////////////////////////////////////////// + "@typescript-eslint/explicit-module-boundary-types": 2, + "camelcase": 0, + "@typescript-eslint/no-inferrable-types": 0, + "flowtype/no-types-missing-file-annotation": 0, + "@typescript-eslint/ban-types": 1, + "@typescript-eslint/no-namespace": 0, + "no-shadow": "off", // turn off eslint rule and use next one instead + "@typescript-eslint/no-shadow": "error", + "@typescript-eslint/no-explicit-any": "error" +} +} diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 168f02e28..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - env: { - node: true, - mocha: true, - }, - parser: '@typescript-eslint/parser', - extends: [ - 'plugin:wdio/recommended', - 'plugin:@typescript-eslint/recommended', - 'prettier/@typescript-eslint', - 'plugin:prettier/recommended', - ], - parserOptions: { - ecmaVersion: 12, - sourceType: 'module', - }, - rules: { - '@typescript-eslint/no-inferrable-types': 0, - '@typescript-eslint/ban-types': 0, - '@typescript-eslint/no-namespace': 0, - '@typescript-eslint/explicit-module-boundary-types': ['error'], - '@typescript-eslint/array-type': ['error', { default: 'generic' }], - '@typescript-eslint/no-explicit-any': ['error'], - }, -}; diff --git a/package.json b/package.json index 69fa828f9..b817822c2 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "@typescript-eslint/parser": "^4.11.0", "chai-as-promised": "^7.1.1", "eslint": "^7.16.0", + "eslint-plugin-no-floating-promise": "^1.0.2", "eslint-config-prettier": "^7.1.0", "eslint-plugin-prettier": "^3.3.0", "eslint-plugin-wdio": "^6.6.0", diff --git a/src/commons/BrowserUtils.ts b/src/commons/BrowserUtils.ts index c718a28f6..eac9ac678 100644 --- a/src/commons/BrowserUtils.ts +++ b/src/commons/BrowserUtils.ts @@ -181,9 +181,9 @@ export namespace BrowserUtils { * to insure the navigation actually happened * @param url url for navigation */ - export async function url(url: string): Promise { - await Reporter.debug(`Navigate to '${url}'`); - await tryBlock(async () => await browser.url(url), `Failed to navigate to '${url}'`); + export async function url(urlToNavigate: string): Promise { + await Reporter.debug(`Navigate to '${urlToNavigate}'`); + await tryBlock(async () => await browser.url(urlToNavigate), `Failed to navigate to '${urlToNavigate}'`); } /** @@ -211,8 +211,8 @@ export namespace BrowserUtils { * Mainly useful for navigation validation * @param url expected current url */ - export async function waitForUrl(url: string): Promise { - const expectedUrl: string = normalizeUrl(url); + export async function waitForUrl(urlToNavigate: string): Promise { + const expectedUrl: string = normalizeUrl(urlToNavigate); await Reporter.debug(`Wait for URL to be , '${expectedUrl}'`); await waitUntil( async () => { @@ -231,14 +231,14 @@ export namespace BrowserUtils { * WDIO return url with backslash at the end of url, * while user mainly passes without the backslash * Removing the last backslash will solve error on url comparison - * @param url url to remove backslash from + * @param urlToNormalize url to remove backslash from */ - export function normalizeUrl(url: string): string { - if (url === null || url === undefined) { - throw new Error(`Illegal URL: '${url}'`); + export function normalizeUrl(urlToNormalize: string): string { + if (urlToNormalize === null || urlToNormalize === undefined) { + throw new Error(`Illegal URL: '${urlToNormalize}'`); } - return url.replace(/\/+$/, ''); + return urlToNormalize.replace(/\/+$/, ''); } /** diff --git a/src/commons/TestRailUtil.ts b/src/commons/TestRailUtil.ts index 67856f9b7..9a77df086 100644 --- a/src/commons/TestRailUtil.ts +++ b/src/commons/TestRailUtil.ts @@ -10,12 +10,10 @@ export namespace TestRailUtil { * Update an array of tests automation field on testrail to automated * @param testIDs array of tests Ids */ - export function setTestsAsAutomatedInTestrail(testIDs: Set): void { + export async function setTestsAsAutomatedInTestrail(testIDs: Set): Promise { console.log(`About to update ${Array.from(testIDs.values())} on testrail`); for (const testId of testIDs) { - changeTestField(testId, TestFields.Automation, TestFields.Automation.fieldOptions.automated).then((res) => { - console.log(`Finished update test C${testId} with status code: ${res.status}`); - }); + await changeTestField(testId, TestFields.Automation, TestFields.Automation.fieldOptions.automated); } } @@ -23,10 +21,10 @@ export namespace TestRailUtil { * Update an array of tests automation field on testrail from specific folder * @param folderPath path of tests files to update */ - export function setTestsAsAutomatedInTestrailFromPath(folderPath?: string): void { + export async function setTestsAsAutomatedInTestrailFromPath(folderPath?: string): Promise { console.log(`Setting tests as 'Automated' from path ${folderPath}`); const testIDs = TestFilesUtils.getTestIdsFromFolder(folderPath); - setTestsAsAutomatedInTestrail(testIDs); + await setTestsAsAutomatedInTestrail(testIDs); } /** diff --git a/src/commons/TestUtils.ts b/src/commons/TestUtils.ts index 9e47b01ec..3cd677a29 100644 --- a/src/commons/TestUtils.ts +++ b/src/commons/TestUtils.ts @@ -50,7 +50,7 @@ export namespace TestUtils { * @param dataTag type of file * configDataFilePath will take from wdio.config file */ - export function getData(dataTag: string = process.env.TEST_DATA_TAG): T { + export async function getData(dataTag: string = process.env.TEST_DATA_TAG): Promise { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const dataFilename = browser.config.configDataFilePath; @@ -61,10 +61,10 @@ export namespace TestUtils { if (dataFilePath === undefined) { throw new Error('Path to data file is incorrect'); } - Reporter.debug(`Getting data from file ${dataFilePath}`); + await Reporter.debug(`Getting data from file ${dataFilePath}`); // eslint-disable-next-line @typescript-eslint/no-var-requires const data: T = require(dataFilePath); - Reporter.debug( + await Reporter.debug( `Received a data ${JSON.stringify(data)} from file by provided tag ${JSON.stringify(data[dataTag])}` ); return data && data[dataTag]; diff --git a/src/test/specs/GetTestDataFileSpec.ts b/src/test/specs/GetTestDataFileSpec.ts index 1dff66c1f..d34a61bea 100644 --- a/src/test/specs/GetTestDataFileSpec.ts +++ b/src/test/specs/GetTestDataFileSpec.ts @@ -12,17 +12,17 @@ interface ITestData { } describeCommon('GetTestDataFileSpec', () => { - it('Check get test data from env file', () => { + it('Check get test data from env file', async () => { process.env.TEST_DATA_TAG = 'test-user'; - Reporter.step('getData reads from file'); - const data: ITestData = TestUtils.getData(); + await Reporter.step('getData reads from file'); + const data: ITestData = await TestUtils.getData(); assert.equal(data.fileName, 'example'); }); - it('Check incorrect user', () => { + it('Check incorrect user', async () => { process.env.TEST_DATA_TAG = 'incorrect-user'; - Reporter.step('undefined returned in case of incorrect data tag'); - const data: ITestData = TestUtils.getData(); + await Reporter.step('undefined returned in case of incorrect data tag'); + const data: ITestData = await TestUtils.getData(); assert.equal(data, undefined); }); }); diff --git a/src/test/specs/NavigateToUrlSpec.ts b/src/test/specs/NavigateToUrlSpec.ts index fe1d6e644..10e57b5d0 100644 --- a/src/test/specs/NavigateToUrlSpec.ts +++ b/src/test/specs/NavigateToUrlSpec.ts @@ -5,8 +5,8 @@ import { describeCommon, sampleAppUrl } from '../TestHelper'; * wdio-allure-ts url action test */ describeCommon('url', () => { - it('navigate successfully', () => { - Reporter.step('Navigate to sample app'); - BrowserUtils.url(sampleAppUrl); + it('navigate successfully', async () => { + await Reporter.step('Navigate to sample app'); + await BrowserUtils.url(sampleAppUrl); }); }); diff --git a/src/test/specs/NormalizeUrlSpec.ts b/src/test/specs/NormalizeUrlSpec.ts index 863a053d6..89a83a4bc 100644 --- a/src/test/specs/NormalizeUrlSpec.ts +++ b/src/test/specs/NormalizeUrlSpec.ts @@ -2,17 +2,17 @@ import { expect } from 'chai'; import { BrowserUtils, Reporter } from '../..'; describe('NormalizeUrl', () => { - it('throw if url is null', () => { + it('throw if url is null', async () => { const url: string = null; - Reporter.step('normalize illegal url'); + await Reporter.step('normalize illegal url'); expect(() => BrowserUtils.normalizeUrl(url)) .to.throw(Error) .with.property('message') .contains(`Illegal URL: '${url}'`); }); - it('throw if url is undefined', () => { - Reporter.step('throw if url is undefined'); + it('throw if url is undefined', async () => { + await Reporter.step('throw if url is undefined'); const url: string = undefined; expect(() => BrowserUtils.normalizeUrl(url)) .to.throw(Error) @@ -20,26 +20,26 @@ describe('NormalizeUrl', () => { .contains(`Illegal URL: '${url}'`); }); - it('expect / removed', () => { + it('expect / removed', async () => { const url: string = 'someString/'; - Reporter.step("expect '/' removed"); + await Reporter.step("expect '/' removed"); expect(BrowserUtils.normalizeUrl(url)).to.equal('someString'); }); - it('expect // removed', () => { + it('expect // removed', async () => { const url: string = 'someString/'; - Reporter.step("expect '//' removed"); + await Reporter.step("expect '//' removed"); expect(BrowserUtils.normalizeUrl(url)).to.equal('someString'); }); - it('empty string', () => { + it('empty string', async () => { const url: string = ''; - Reporter.step('empty string'); + await Reporter.step('empty string'); expect(BrowserUtils.normalizeUrl(url)).to.equal(''); }); - it('//// to be empty', () => { - Reporter.step('//// to be empty'); + it('//// to be empty', async () => { + await Reporter.step('//// to be empty'); const url: string = '////'; expect(BrowserUtils.normalizeUrl(url)).to.equal(''); }); diff --git a/src/test/specs/TestUtilsSpec.ts b/src/test/specs/TestUtilsSpec.ts index b9bfeed6f..639d37681 100644 --- a/src/test/specs/TestUtilsSpec.ts +++ b/src/test/specs/TestUtilsSpec.ts @@ -3,59 +3,59 @@ import { Reporter, TestUtils } from '../..'; describe('TestUtilsSpec', () => { describe('randomStringTest', () => { - it('default random string length', () => { - Reporter.step('generate random string'); + it('default random string length', async () => { + await Reporter.step('generate random string'); const randStr: string = TestUtils.randomString(); - Reporter.step('Validate strings default length'); + await Reporter.step('Validate strings default length'); assert.equal(randStr.length, 5); }); - it('random string of provided length', () => { - Reporter.step('generate random string with given length'); + it('random string of provided length', async () => { + await Reporter.step('generate random string with given length'); const randStr: string = TestUtils.randomString(7); - Reporter.step('Validate strings length'); + await Reporter.step('Validate strings length'); assert.equal(randStr.length, 7); }); - it('strings are randoms', () => { - Reporter.step('generate random string 1'); + it('strings are randoms', async () => { + await Reporter.step('generate random string 1'); const randStr1: string = TestUtils.randomString(); - Reporter.step('generate random string 2'); + await Reporter.step('generate random string 2'); const randStr2: string = TestUtils.randomString(); - Reporter.step('Validate strings are not equal'); + await Reporter.step('Validate strings are not equal'); assert.notEqual(randStr1, randStr2); }); - it('letters only', () => { - Reporter.step('Generate letters only string'); + it('letters only', async () => { + await Reporter.step('Generate letters only string'); const randStr = TestUtils.randomString(5, true); - Reporter.step('Validate string contains letters only'); + await Reporter.step('Validate string contains letters only'); assert.isTrue(!/\d/.test(randStr)); }); }); describe('extractNumbersFromString', () => { - it('string contains letters and numbers', () => { - Reporter.step('Validate extractNumbersFromString'); + it('string contains letters and numbers', async () => { + await Reporter.step('Validate extractNumbersFromString'); const str: string = 'abc2de3mnb'; const expectedNumber = 23; assert.equal(Number(TestUtils.extractNumbersFromString(str)), expectedNumber); }); }); describe('isTimePassed', () => { - it('expect to return true', () => { - Reporter.step('Validate isTimePassed - true'); + it('expect to return true', async () => { + await Reporter.step('Validate isTimePassed - true'); const expectedDate = new Date(2000, 1); assert.isTrue(TestUtils.isTimePassed(expectedDate, 5)); }); - it('expect to return false', () => { - Reporter.step('Validate isTimePassed - false'); + it('expect to return false', async () => { + await Reporter.step('Validate isTimePassed - false'); const expectedDate = new Date(3000, 1); assert.isNotTrue(TestUtils.isTimePassed(expectedDate, 5)); }); diff --git a/src/test/specs/startNetworkAuditSpec.ts b/src/test/specs/startNetworkAuditSpec.ts index d7bb22485..a2077c535 100644 --- a/src/test/specs/startNetworkAuditSpec.ts +++ b/src/test/specs/startNetworkAuditSpec.ts @@ -10,11 +10,11 @@ interface NetworkLog { * DevTools - Start network audit */ describeCommon('startNetworkAudit', () => { - it('successfully start and read network audit', () => { + it('successfully start and read network audit', async () => { const expectedLog: NetworkLog = { url: 'http://placekitten.com/480/480', status: 200 }; const networkLogs: Array = []; - Reporter.step('Start network log'); + await Reporter.step('Start network log'); // eslint-disable-next-line @typescript-eslint/no-explicit-any browser.on('Network.responseReceived', (params: any) => { networkLogs.push({ @@ -23,11 +23,11 @@ describeCommon('startNetworkAudit', () => { }); }); - Reporter.step('navigate to sample app'); - BrowserUtils.url(sampleAppUrl); + await Reporter.step('navigate to sample app'); + await BrowserUtils.url(sampleAppUrl); - Reporter.step('Wait for new logs'); - BrowserUtils.waitUntil( + await Reporter.step('Wait for new logs'); + await BrowserUtils.waitUntil( () => { return networkLogs.some((log) => log.url === expectedLog.url && Number(log.status) === expectedLog.status); }, diff --git a/tsconfig.json b/tsconfig.json index 3d501abd4..8975dd22d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,15 +3,21 @@ "types": ["node", "webdriverio/async", "mocha", "@wdio/mocha-framework", "@wdio/devtools-service"], "target": "es6", "module": "commonjs", - "declaration": true, - "outDir": "lib/", - "rootDir": "src/", + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "removeComments": true, "noUnusedLocals": true, "noUnusedParameters": true, - "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "sourceMap": true, + "resolveJsonModule": true, + "outDir": "lib/", + "rootDir": "src/", + "declaration": true, "esModuleInterop": true, - "skipLibCheck": true //todo temporary solution since there is type missmatch in the reportportal package + "skipLibCheck": true }, - "exclude": ["node_modules", "lib", "src/test"], + "compileOnSave": false } diff --git a/yarn.lock b/yarn.lock index 366a4c77c..dc59b4544 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2860,6 +2860,13 @@ eslint-config-prettier@^7.1.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz#f4a4bd2832e810e8cc7c1411ec85b3e85c0c53f9" integrity sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg== +eslint-plugin-no-floating-promise@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-no-floating-promise/-/eslint-plugin-no-floating-promise-1.0.2.tgz#5176e89cc84682a2ee7e9a523019552a751de82c" + integrity sha512-ccbyIlvDuKJOrwypw9NWn6CIxTK+/CYARhsqMyP6cXYgIFcNFs01sGXOqq8XzOJFw02Umkj6hCnffaV6nSiqyw== + dependencies: + requireindex "1.2.0" + eslint-plugin-prettier@^3.3.0: version "3.4.0" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz#cdbad3bf1dbd2b177e9825737fe63b476a08f0c7" @@ -6047,6 +6054,11 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +requireindex@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" + integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== + resolve-alpn@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.2.tgz#30b60cfbb0c0b8dc897940fe13fe255afcdd4d28"