diff --git a/.github/workflows/appium.yml b/.github/workflows/appium.yml index ae181295c..59845be91 100644 --- a/.github/workflows/appium.yml +++ b/.github/workflows/appium.yml @@ -4,9 +4,6 @@ on: push: branches: - master - pull_request: - branches: - - '**' env: CI: true diff --git a/.github/workflows/dtslint.yml b/.github/workflows/dtslint.yml new file mode 100644 index 000000000..c6fcc882a --- /dev/null +++ b/.github/workflows/dtslint.yml @@ -0,0 +1,25 @@ +name: Typings tests + +on: + push: + branches: + - master + pull_request: + branches: + - '**' + +jobs: + test: + runs-on: ubuntu-18.04 + strategy: + matrix: + node-version: [12.x] + steps: + - uses: actions/checkout@v1 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm run def + - run: npm run dtslint diff --git a/docs/webapi/clearField.mustache b/docs/webapi/clearField.mustache index 26d46f1ec..afebc044c 100644 --- a/docs/webapi/clearField.mustache +++ b/docs/webapi/clearField.mustache @@ -5,4 +5,4 @@ I.clearField('Email'); I.clearField('user[email]'); I.clearField('#email'); ``` -@param {string|object} editable field located by label|name|CSS|XPath|strict locator. \ No newline at end of file +@param {LocatorOrString} editable field located by label|name|CSS|XPath|strict locator. diff --git a/docs/webapi/closeCurrentTab.mustache b/docs/webapi/closeCurrentTab.mustache new file mode 100644 index 000000000..030ed99e8 --- /dev/null +++ b/docs/webapi/closeCurrentTab.mustache @@ -0,0 +1,5 @@ + Close current tab. + + ```js + I.closeCurrentTab(); + ``` diff --git a/docs/webapi/closeOtherTabs.mustache b/docs/webapi/closeOtherTabs.mustache new file mode 100644 index 000000000..68d03c036 --- /dev/null +++ b/docs/webapi/closeOtherTabs.mustache @@ -0,0 +1,6 @@ + Close all tabs except for the current one. + + + ```js + I.closeOtherTabs(); + ``` diff --git a/docs/webapi/dragAndDrop.mustache b/docs/webapi/dragAndDrop.mustache index f8a84784d..59a3f2f55 100644 --- a/docs/webapi/dragAndDrop.mustache +++ b/docs/webapi/dragAndDrop.mustache @@ -4,5 +4,5 @@ Drag an item to a destination element. I.dragAndDrop('#dragHandle', '#container'); ``` -@param {string|object} srcElement located by CSS|XPath|strict locator. -@param {string|object} destElement located by CSS|XPath|strict locator. \ No newline at end of file +@param {LocatorOrString} srcElement located by CSS|XPath|strict locator. +@param {LocatorOrString} destElement located by CSS|XPath|strict locator. diff --git a/docs/webapi/grabAllWindowHandles.mustache b/docs/webapi/grabAllWindowHandles.mustache new file mode 100644 index 000000000..fdc86db55 --- /dev/null +++ b/docs/webapi/grabAllWindowHandles.mustache @@ -0,0 +1,7 @@ +Get all Window Handles. +Useful for referencing a specific handle when calling `I.switchToWindow(handle)` + +```js +const windows = await I.grabAllWindowHandles(); +``` +@returns {Promise} diff --git a/docs/webapi/grabBrowserLogs.mustache b/docs/webapi/grabBrowserLogs.mustache index 436d44bf9..f504f2357 100644 --- a/docs/webapi/grabBrowserLogs.mustache +++ b/docs/webapi/grabBrowserLogs.mustache @@ -6,4 +6,4 @@ let logs = await I.grabBrowserLogs(); console.log(JSON.stringify(logs)) ``` -@returns {Promise>} all browser logs \ No newline at end of file +@returns {Promise|undefined} all browser logs diff --git a/docs/webapi/grabCookie.mustache b/docs/webapi/grabCookie.mustache index a16ce54a9..730e609bd 100644 --- a/docs/webapi/grabCookie.mustache +++ b/docs/webapi/grabCookie.mustache @@ -8,4 +8,4 @@ assert(cookie.value, '123456'); ``` @param {?string} [name=null] cookie name. -@returns {Promise} attribute value \ No newline at end of file +@returns {Promise|Promise} attribute value diff --git a/docs/webapi/grabCurrentWindowHandle.mustache b/docs/webapi/grabCurrentWindowHandle.mustache new file mode 100644 index 000000000..b2ff9d489 --- /dev/null +++ b/docs/webapi/grabCurrentWindowHandle.mustache @@ -0,0 +1,6 @@ +Get the current Window Handle. +Useful for referencing it when calling `I.switchToWindow(handle)` +```js +const window = await I.grabCurrentWindowHandle(); +``` +@returns {Promise} diff --git a/docs/webapi/grabElementBoundingRect.mustache b/docs/webapi/grabElementBoundingRect.mustache index 2b3bb851c..8d4d28d5b 100644 --- a/docs/webapi/grabElementBoundingRect.mustache +++ b/docs/webapi/grabElementBoundingRect.mustache @@ -15,6 +15,6 @@ To get only one metric use second parameter: const width = await I.grabElementBoundingRect('h3', 'width'); // width == 527 ``` -@param {string|object} locator element located by CSS|XPath|strict locator. -@param {string} elementSize x, y, width or height of the given element. -@returns {object} Element bounding rectangle \ No newline at end of file +@param {LocatorOrString} locator element located by CSS|XPath|strict locator. +@param {string=} elementSize x, y, width or height of the given element. +@returns {Promise|Promise} Element bounding rectangle diff --git a/docs/webapi/grabNumberOfOpenTabs.mustache b/docs/webapi/grabNumberOfOpenTabs.mustache index 14531fc4d..075f2b2ac 100644 --- a/docs/webapi/grabNumberOfOpenTabs.mustache +++ b/docs/webapi/grabNumberOfOpenTabs.mustache @@ -5,4 +5,4 @@ Resumes test execution, so **should be used inside async function with `await`** let tabs = await I.grabNumberOfOpenTabs(); ``` -@returns {Promise} number of open tabs \ No newline at end of file +@returns {Promise} number of open tabs diff --git a/docs/webapi/grabPageScrollPosition.mustache b/docs/webapi/grabPageScrollPosition.mustache index b34b006d6..b6a2311d1 100644 --- a/docs/webapi/grabPageScrollPosition.mustache +++ b/docs/webapi/grabPageScrollPosition.mustache @@ -5,4 +5,4 @@ Resumes test execution, so **should be used inside an async function with `await let { x, y } = await I.grabPageScrollPosition(); ``` -@returns {Promise>} scroll position \ No newline at end of file +@returns {Promise} scroll position diff --git a/docs/webapi/grabPopupText.mustache b/docs/webapi/grabPopupText.mustache new file mode 100644 index 000000000..964b49218 --- /dev/null +++ b/docs/webapi/grabPopupText.mustache @@ -0,0 +1,5 @@ +Grab the text within the popup. If no popup is visible then it will return null. +```js +await I.grabPopupText(); +``` +@returns {Promise} diff --git a/docs/webapi/openNewTab.mustache b/docs/webapi/openNewTab.mustache new file mode 100644 index 000000000..a81321ea2 --- /dev/null +++ b/docs/webapi/openNewTab.mustache @@ -0,0 +1,5 @@ + Open new tab and switch to it. + + ```js + I.openNewTab(); + ``` diff --git a/docs/webapi/scrollIntoView.mustache b/docs/webapi/scrollIntoView.mustache index 930bf77d0..2a0e445a8 100644 --- a/docs/webapi/scrollIntoView.mustache +++ b/docs/webapi/scrollIntoView.mustache @@ -6,5 +6,5 @@ I.scrollIntoView('#submit', true); I.scrollIntoView('#submit', { behavior: "smooth", block: "center", inline: "center" }); ``` -@param {string|object} locator located by CSS|XPath|strict locator. -@param {boolean|object} alignToTop (optional) or scrollIntoViewOptions (optional), see https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView. +@param {LocatorOrString} locator located by CSS|XPath|strict locator. +@param {ScrollIntoViewOptions} scrollIntoViewOptions see https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView. diff --git a/docs/webapi/seeTitleEquals.mustache b/docs/webapi/seeTitleEquals.mustache new file mode 100644 index 000000000..9d157cb32 --- /dev/null +++ b/docs/webapi/seeTitleEquals.mustache @@ -0,0 +1,7 @@ + Checks that title is equal to provided one. + + ```js + I.seeTitleEquals('Test title.'); + ``` + + @param {string} text value to check. diff --git a/docs/webapi/selectOption.mustache b/docs/webapi/selectOption.mustache index efa2e6b32..764dd8e44 100644 --- a/docs/webapi/selectOption.mustache +++ b/docs/webapi/selectOption.mustache @@ -16,5 +16,5 @@ Provide an array for the second argument to select multiple options. ```js I.selectOption('Which OS do you use?', ['Android', 'iOS']); ``` -@param {CodeceptJS.LocatorOrString} select field located by label|name|CSS|XPath|strict locator. -@param {string|Array<*>} option visible text or value of option. \ No newline at end of file +@param {LocatorOrString} select field located by label|name|CSS|XPath|strict locator. +@param {string|Array<*>} option visible text or value of option. diff --git a/docs/webapi/setCookie.mustache b/docs/webapi/setCookie.mustache index c792d8c1b..71add5d9e 100644 --- a/docs/webapi/setCookie.mustache +++ b/docs/webapi/setCookie.mustache @@ -12,4 +12,4 @@ I.setCookie([ ]); ``` -@param {object|array} cookie a cookie object or array of cookie objects. \ No newline at end of file +@param {Cookie|Array} cookie a cookie object or array of cookie objects. diff --git a/docs/webapi/setGeoLocation.mustache b/docs/webapi/setGeoLocation.mustache index ab55fdeb0..ce45fd76d 100644 --- a/docs/webapi/setGeoLocation.mustache +++ b/docs/webapi/setGeoLocation.mustache @@ -8,4 +8,4 @@ I.setGeoLocation(121.21, 11.56, 10); @param {number} latitude to set. @param {number} longitude to set -@param {number} altitude (optional, null by default) to set \ No newline at end of file +@param {number=} altitude (optional, null by default) to set diff --git a/docs/webapi/switchToNextTab.mustache b/docs/webapi/switchToNextTab.mustache new file mode 100644 index 000000000..114a8c32f --- /dev/null +++ b/docs/webapi/switchToNextTab.mustache @@ -0,0 +1,9 @@ + Switch focus to a particular tab by its number. It waits tabs loading and then switch tab. + + ```js + I.switchToNextTab(); + I.switchToNextTab(2); + ``` + + @param {number} [num] (optional) number of tabs to switch forward, default: 1. + @param {number | null} [sec] (optional) time in seconds to wait. diff --git a/docs/webapi/switchToPreviousTab.mustache b/docs/webapi/switchToPreviousTab.mustache new file mode 100644 index 000000000..4d9044114 --- /dev/null +++ b/docs/webapi/switchToPreviousTab.mustache @@ -0,0 +1,9 @@ + Switch focus to a particular tab by its number. It waits tabs loading and then switch tab. + + ```js + I.switchToPreviousTab(); + I.switchToPreviousTab(2); + ``` + + @param {number} [num] (optional) number of tabs to switch backward, default: 1. + @param {number?} [sec] (optional) time in seconds to wait. diff --git a/docs/webapi/waitForValue.mustache b/docs/webapi/waitForValue.mustache index e3c330900..0e9f8a621 100644 --- a/docs/webapi/waitForValue.mustache +++ b/docs/webapi/waitForValue.mustache @@ -4,6 +4,6 @@ Waits for the specified value to be in value attribute. I.waitForValue('//input', "GoodValue"); ``` -@param {string|object} field input field. +@param {LocatorOrString} field input field. @param {string }value expected value. -@param {number} [sec=1] (optional, `1` by default) time in seconds to wait \ No newline at end of file +@param {number} [sec=1] (optional, `1` by default) time in seconds to wait diff --git a/lib/command/definitions.js b/lib/command/definitions.js index b219009eb..458c2d569 100644 --- a/lib/command/definitions.js +++ b/lib/command/definitions.js @@ -48,12 +48,12 @@ module.exports = function (genPath, options) { helperPaths[name] = require; helperNames.push(name); } else { - helperNames.push(`CodeceptJS.${name}`); + helperNames.push(name); } } const supportObject = new Map(); - supportObject.set('I', 'CodeceptJS.I'); + supportObject.set('I', 'I'); for (const name in codecept.config.include) { const includePath = codecept.config.include[name]; if (name === 'I' || name === translations.I) { diff --git a/lib/helper/WebDriver.js b/lib/helper/WebDriver.js index 8a0030853..5081084a7 100644 --- a/lib/helper/WebDriver.js +++ b/lib/helper/WebDriver.js @@ -1194,7 +1194,6 @@ class WebDriver extends Helper { /** * {{> seeInTitle }} - * */ async seeInTitle(text) { const title = await this.browser.getTitle(); @@ -1202,13 +1201,7 @@ class WebDriver extends Helper { } /** - * Checks that title is equal to provided one. - * - * ```js - * I.seeTitleEquals('Test title.'); - * ``` - * - * @param {string} text value to check. + * {{> seeTitleEquals }} */ async seeTitleEquals(text) { const title = await this.browser.getTitle(); @@ -1217,7 +1210,6 @@ class WebDriver extends Helper { /** * {{> dontSeeInTitle }} - * */ async dontSeeInTitle(text) { const title = await this.browser.getTitle(); @@ -1226,7 +1218,6 @@ class WebDriver extends Helper { /** * {{> grabTitle }} - * */ async grabTitle() { const title = await this.browser.getTitle(); @@ -1352,13 +1343,7 @@ class WebDriver extends Helper { } /** - * Get JS log from browser. Log buffer is reset after each request. - * - * ```js - * let logs = await I.grabBrowserLogs(); - * console.log(JSON.stringify(logs)) - * ``` - * @returns {Promise} + * {{> grabBrowserLogs }} */ async grabBrowserLogs() { if (this.browser.isW3C) { @@ -1575,7 +1560,6 @@ class WebDriver extends Helper { /** * {{> moveCursorTo }} - * */ async moveCursorTo(locator, xOffset, yOffset) { const res = await this._locate(withStrictLocator(locator), true); @@ -1587,7 +1571,6 @@ class WebDriver extends Helper { /** * {{> saveScreenshot }} - * */ async saveScreenshot(fileName, fullPage = false) { const outputFile = screenshotOutputFolder(fileName); @@ -1639,7 +1622,6 @@ class WebDriver extends Helper { /** * {{> clearCookie }} - * */ async clearCookie(cookie) { return this.browser.deleteCookies(cookie); @@ -1647,7 +1629,6 @@ class WebDriver extends Helper { /** * {{> seeCookie }} - * */ async seeCookie(name) { const cookie = await this.browser.getCookies([name]); @@ -1656,7 +1637,6 @@ class WebDriver extends Helper { /** * {{> dontSeeCookie }} - * */ async dontSeeCookie(name) { const cookie = await this.browser.getCookies([name]); @@ -1665,7 +1645,6 @@ class WebDriver extends Helper { /** * {{> grabCookie }} - * */ async grabCookie(name) { if (!name) return this.browser.getCookies(); @@ -1715,11 +1694,7 @@ class WebDriver extends Helper { } /** - * Grab the text within the popup. If no popup is visible then it will return null. - * - * ```js - * await I.grabPopupText(); - * ``` + * {{> grabPopupText }} */ async grabPopupText() { try { @@ -1889,24 +1864,14 @@ class WebDriver extends Helper { } /** - * Get all Window Handles. - * Useful for referencing a specific handle when calling `I.switchToWindow(handle)` - * - * ```js - * const windows = await I.grabAllWindowHandles(); - * ``` + * {{> grabAllWindowHandles }} */ async grabAllWindowHandles() { return this.browser.getWindowHandles(); } /** - * Get the current Window Handle. - * Useful for referencing it when calling `I.switchToWindow(handle)` - * - * ```js - * const window = await I.grabCurrentWindowHandle(); - * ``` + * {{> grabCurrentWindowHandle }} */ async grabCurrentWindowHandle() { return this.browser.getWindowHandle(); @@ -1924,18 +1889,14 @@ class WebDriver extends Helper { * // ... do something * await I.switchToWindow( window ); * ``` + * @param {string} window name of window handle. */ async switchToWindow(window) { await this.browser.switchToWindow(window); } /** - * Close all tabs except for the current one. - * - * - * ```js - * I.closeOtherTabs(); - * ``` + * {{> closeOtherTabs }} */ async closeOtherTabs() { const handles = await this.browser.getWindowHandles(); @@ -1951,7 +1912,6 @@ class WebDriver extends Helper { /** * {{> wait }} - * */ async wait(sec) { return new Promise(resolve => setTimeout(resolve, sec * 1000)); @@ -1959,7 +1919,6 @@ class WebDriver extends Helper { /** * {{> waitForEnabled }} - * */ async waitForEnabled(locator, sec = null) { const aSec = sec || this.options.waitForTimeout; @@ -2024,13 +1983,6 @@ class WebDriver extends Helper { }); } - async waitUntilExists(locator, sec = null) { - console.log(`waitUntilExists deprecated: - * use 'waitForElement' to wait for element to be attached - * use 'waitForDetached to wait for element to be removed'`); - return this.waitForStalenessOf(locator, sec); - } - /** * {{> waitInUrl }} */ @@ -2220,7 +2172,6 @@ class WebDriver extends Helper { /** * {{> waitForInvisible }} - * */ async waitForInvisible(locator, sec = null) { const aSec = sec || this.options.waitForTimeout; @@ -2242,20 +2193,13 @@ class WebDriver extends Helper { /** * {{> waitToHide }} - * */ async waitToHide(locator, sec = null) { return this.waitForInvisible(locator, sec); } - async waitForStalenessOf(locator, sec = null) { - console.log('waitForStalenessOf deprecated. Use waitForDetached instead'); - return this.waitForDetached(locator, sec); - } - /** * {{> waitForDetached }} - * */ async waitForDetached(locator, sec = null) { const aSec = sec || this.options.waitForTimeout; @@ -2279,7 +2223,6 @@ class WebDriver extends Helper { /** * {{> waitForFunction }} - * */ async waitForFunction(fn, argsOrSec = null, sec = null) { let args = []; @@ -2300,7 +2243,6 @@ class WebDriver extends Helper { /** * {{> waitUntil }} - * */ async waitUntil(fn, sec = null, timeoutMsg = null, interval = null) { const aSec = sec || this.options.waitForTimeout; @@ -2313,7 +2255,6 @@ class WebDriver extends Helper { /** * {{> switchTo }} - * */ async switchTo(locator) { this.browser.isInsideFrame = true; @@ -2331,15 +2272,7 @@ class WebDriver extends Helper { } /** - * Switch focus to a particular tab by its number. It waits tabs loading and then switch tab. - * - * ```js - * I.switchToNextTab(); - * I.switchToNextTab(2); - * ``` - * - * @param {number} [num] (optional) number of tabs to switch forward, default: 1. - * @param {number | null} [sec] (optional) time in seconds to wait. + * {{> switchToNextTab }} */ async switchToNextTab(num = 1, sec = null) { const aSec = sec || this.options.waitForTimeout; @@ -2370,15 +2303,7 @@ class WebDriver extends Helper { } /** - * Switch focus to a particular tab by its number. It waits tabs loading and then switch tab. - * - * ```js - * I.switchToPreviousTab(); - * I.switchToPreviousTab(2); - * ``` - * - * @param {number} [num] (optional) number of tabs to switch backward, default: 1. - * @param {number?} [sec] (optional) time in seconds to wait. + * {{> switchToPreviousTab }} */ async switchToPreviousTab(num = 1, sec = null) { const aSec = sec || this.options.waitForTimeout; @@ -2409,11 +2334,7 @@ class WebDriver extends Helper { } /** - * Close current tab. - * - * ```js - * I.closeCurrentTab(); - * ``` + * {{> closeCurrentTab }} */ async closeCurrentTab() { await this.browser.closeWindow(); @@ -2422,11 +2343,7 @@ class WebDriver extends Helper { } /** - * Open new tab and switch to it. - * - * ```js - * I.openNewTab(); - * ``` + * {{> openNewTab }} */ async openNewTab(url = 'about:blank', windowName = null) { const client = this.browser; @@ -2500,7 +2417,6 @@ class WebDriver extends Helper { /** * {{> setGeoLocation }} - * */ async setGeoLocation(latitude, longitude, altitude = null) { if (altitude) { diff --git a/package.json b/package.json index 2b1ced953..63700fa13 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,10 @@ }, "files": [ "bin", - "docs", + "docs/**/*.md", "lib", "translations", - "typings" + "typings/**/*.d.ts" ], "main": "lib/index.js", "typings": "typings/index.d.ts", @@ -49,7 +49,8 @@ "def": "./runio.js def", "dev:graphql": "nodemon test/data/graphql/index.js", "publish:site": "./runio.js publish:site", - "update-contributor-faces": "contributor-faces ." + "update-contributor-faces": "contributor-faces .", + "dtslint": "dtslint typings --localTs './node_modules/typescript/lib'" }, "dependencies": { "acorn": "^7.1.0", @@ -99,6 +100,7 @@ "chai-as-promised": "^5.2.0", "chai-subset": "^1.6.0", "contributor-faces": "^1.0.3", + "dtslint": "^3.6.12", "documentation": "^12.3.0", "eslint": "^6.8.0", "expect": "^26.0.1", @@ -126,13 +128,13 @@ "sinon-chai": "^3.5.0", "testcafe": "^1.8.6", "ts-morph": "^3.1.3", + "typescript": "^3.7.5", + "xml2js": "^0.4.23", "tsd-jsdoc": "^2.5.0", - "typescript": "^2.9.2", "wdio-docker-service": "^1.5.0", "webdriverio": "^6.1.19", "xmldom": "^0.1.31", - "xpath": "0.0.27", - "xml2js": "^0.4.23" + "xpath": "0.0.27" }, "engines": { "node": ">=8.9.1", diff --git a/test/runner/allure_test.js b/test/runner/allure_test.js index a65044ada..0af5d87b2 100644 --- a/test/runner/allure_test.js +++ b/test/runner/allure_test.js @@ -77,13 +77,13 @@ describe('CodeceptJS Allure Plugin', function () { it('should report skipped features', (done) => { exec(codecept_run_config('skipped_feature.conf.js'), (err, stdout) => { - stdout.should.include('OK | 0 passed, 2 skipped'); + expect(stdout).toContain('OK | 0 passed, 2 skipped'); const files = fs.readdirSync(path.join(codecept_dir, 'output/skipped')); const reports = files.map((testResultPath) => { - assert(testResultPath.match(/\.xml$/), 'not a xml file'); + expect(testResultPath.match(/\.xml$/)).toBeTruthy(); return fs.readFileSync(path.join(codecept_dir, 'output/skipped', testResultPath), 'utf8'); }).join(' '); - reports.should.include('Skipped due to "skip" on Feature.'); + expect(reports).toContain('Skipped due to "skip" on Feature.'); done(); }); }); diff --git a/test/runner/definitions_test.js b/test/runner/definitions_test.js index 0f96f484f..21ef4cfc9 100644 --- a/test/runner/definitions_test.js +++ b/test/runner/definitions_test.js @@ -155,7 +155,7 @@ describe('Definitions', function () { returned.should.containSubset([ { properties: [ - { name: 'I', type: 'CodeceptJS.I' }, + { name: 'I', type: 'I' }, { name: 'MyPage', type: 'MyPage' }, ], }, @@ -172,7 +172,7 @@ describe('Definitions', function () { const definitionsFile = types.getSourceFileOrThrow(pathOfStaticDefinitions); const returned = getReturnStructure(definitionsFile.getFunctionOrThrow('inject')); returned.should.containSubset([{ - properties: [{ name: 'I', type: 'CodeceptJS.I' }], + properties: [{ name: 'I', type: 'I' }], }]); done(); }); @@ -186,7 +186,7 @@ describe('Definitions', function () { const definitionsFile = types.getSourceFileOrThrow(`${codecept_dir}/steps.d.ts`); const CallbackOrder = definitionsFile.getNamespaceOrThrow('CodeceptJS').getInterfaceOrThrow('SupportObject').getStructure(); CallbackOrder.properties.should.containSubset([ - { name: 'I', type: 'CodeceptJS.I' }, + { name: 'I', type: 'I' }, { name: 'MyPage', type: 'MyPage' }, { name: 'SecondPage', type: 'SecondPage' }, ]); diff --git a/test/runner/dry_run_test.js b/test/runner/dry_run_test.js index 03a46650d..59cdbf990 100644 --- a/test/runner/dry_run_test.js +++ b/test/runner/dry_run_test.js @@ -5,7 +5,7 @@ const exec = require('child_process').exec; const runner = path.join(__dirname, '/../../bin/codecept.js'); const codecept_dir = path.join(__dirname, '/../data/sandbox'); const codecept_run = `${runner} dry-run`; -const codecept_run_config = config => `${codecept_run} --config ${codecept_dir}/${config}`; +const codecept_run_config = (config, grep) => `${codecept_run} --config ${codecept_dir}/${config} ${grep ? `--grep "${grep}"` : ''}`; const char = require('figures').checkboxOff; describe('dry-run command', () => { @@ -159,7 +159,7 @@ describe('dry-run command', () => { }); it('should work with inject() keyword', (done) => { - exec(`${codecept_run_config('configs/pageObjects/codecept.inject.po.json')} --debug`, (err, stdout) => { + exec(`${codecept_run_config('configs/pageObjects/codecept.inject.po.json', 'check current dir')} --debug`, (err, stdout) => { const lines = stdout.split('\n'); expect(stdout).toContain('injected'); expect(lines).toEqual( diff --git a/tsconfig.json b/tsconfig.json index b7c3edd1f..15445914a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,5 +16,8 @@ "include": [ "lib", "typings" + ], + "exclude": [ + "typings/tests" ] -} \ No newline at end of file +} diff --git a/typings/Mocha.d.ts b/typings/Mocha.d.ts index f1ea30558..cb73a2a1c 100644 --- a/typings/Mocha.d.ts +++ b/typings/Mocha.d.ts @@ -1,4 +1,4 @@ -declare module Mocha { +declare namespace Mocha { class SuiteRunnable { private _beforeEach; private _beforeAll; @@ -11,9 +11,9 @@ declare module Mocha { private _retries; private _onlyTests; private _onlySuites; - + constructor(title: string, parentContext?: Context); - + ctx: Context; suites: Suite[]; tests: Test[]; @@ -23,7 +23,7 @@ declare module Mocha { delayed: boolean; parent: Suite | undefined; title: string; - + /** * Create a new `Suite` with the given `title` and parent `Suite`. When a suite * with the same title is already present, that suite is returned to provide @@ -32,217 +32,161 @@ declare module Mocha { * @see https://mochajs.org/api/mocha#.exports.create */ static create(parent: Suite, title: string): Suite; - + /** * Return a clone of this `Suite`. * * @see https://mochajs.org/api/Mocha.Suite.html#clone */ clone(): Suite; - + /** * Get timeout `ms`. * * @see https://mochajs.org/api/Mocha.Suite.html#timeout */ timeout(): number; - + /** * Set timeout `ms` or short-hand such as "2s". * * @see https://mochajs.org/api/Mocha.Suite.html#timeout */ timeout(ms: string | number): this; - + /** * Get number of times to retry a failed test. * * @see https://mochajs.org/api/Mocha.Suite.html#retries */ retries(): number; - + /** * Set number of times to retry a failed test. * * @see https://mochajs.org/api/Mocha.Suite.html#retries */ retries(n: string | number): this; - + /** * Get whether timeouts are enabled. * * @see https://mochajs.org/api/Mocha.Suite.html#enableTimeouts */ enableTimeouts(): boolean; - + /** * Set whether timeouts are `enabled`. * * @see https://mochajs.org/api/Mocha.Suite.html#enableTimeouts */ enableTimeouts(enabled: boolean): this; - + /** * Get slow `ms`. * * @see https://mochajs.org/api/Mocha.Suite.html#slow */ slow(): number; - + /** * Set slow `ms` or short-hand such as "2s". * * @see https://mochajs.org/api/Mocha.Suite.html#slow */ slow(ms: string | number): this; - + /** * Get whether to bail after first error. * * @see https://mochajs.org/api/Mocha.Suite.html#bail */ bail(): boolean; - + /** * Set whether to bail after first error. * * @see https://mochajs.org/api/Mocha.Suite.html#bail */ bail(bail: boolean): this; - + /** * Check if this suite or its parent suite is marked as pending. * * @see https://mochajs.org/api/Mocha.Suite.html#isPending */ isPending(): boolean; - - /** - * Run `fn(test[, done])` before running tests. - * - * @see https://mochajs.org/api/Mocha.Suite.html#beforeAll - */ - beforeAll(fn?: Func): this; - - /** - * Run `fn(test[, done])` before running tests. - * - * @see https://mochajs.org/api/Mocha.Suite.html#beforeAll - */ - beforeAll(fn?: AsyncFunc): this; - + /** * Run `fn(test[, done])` before running tests. * * @see https://mochajs.org/api/Mocha.Suite.html#beforeAll */ - beforeAll(title: string, fn?: Func): this; - + beforeAll(fn?: Func | AsyncFunc): this; + /** * Run `fn(test[, done])` before running tests. * * @see https://mochajs.org/api/Mocha.Suite.html#beforeAll */ - beforeAll(title: string, fn?: AsyncFunc): this; - - /** - * Run `fn(test[, done])` after running tests. - * - * @see https://mochajs.org/api/Mocha.Suite.html#afterAll - */ - afterAll(fn?: Func): this; - - /** - * Run `fn(test[, done])` after running tests. - * - * @see https://mochajs.org/api/Mocha.Suite.html#afterAll - */ - afterAll(fn?: AsyncFunc): this; - + beforeAll(title: string, fn?: Func | AsyncFunc): this; + /** * Run `fn(test[, done])` after running tests. * * @see https://mochajs.org/api/Mocha.Suite.html#afterAll */ - afterAll(title: string, fn?: Func): this; - + afterAll(fn?: Func | AsyncFunc): this; + /** * Run `fn(test[, done])` after running tests. * * @see https://mochajs.org/api/Mocha.Suite.html#afterAll */ - afterAll(title: string, fn?: AsyncFunc): this; - - /** - * Run `fn(test[, done])` before each test case. - * - * @see https://mochajs.org/api/Mocha.Suite.html#beforeEach - */ - beforeEach(fn?: Func): this; - - /** - * Run `fn(test[, done])` before each test case. - * - * @see https://mochajs.org/api/Mocha.Suite.html#beforeEach - */ - beforeEach(fn?: AsyncFunc): this; - + afterAll(title: string, fn?: Func | AsyncFunc): this; + /** * Run `fn(test[, done])` before each test case. * * @see https://mochajs.org/api/Mocha.Suite.html#beforeEach */ - beforeEach(title: string, fn?: Func): this; - + beforeEach(fn?: Func | AsyncFunc): this; + /** * Run `fn(test[, done])` before each test case. * * @see https://mochajs.org/api/Mocha.Suite.html#beforeEach */ - beforeEach(title: string, fn?: AsyncFunc): this; - - /** - * Run `fn(test[, done])` after each test case. - * - * @see https://mochajs.org/api/Mocha.Suite.html#afterEach - */ - afterEach(fn?: Func): this; - - /** - * Run `fn(test[, done])` after each test case. - * - * @see https://mochajs.org/api/Mocha.Suite.html#afterEach - */ - afterEach(fn?: AsyncFunc): this; - + beforeEach(title: string, fn?: Func | AsyncFunc): this; + /** * Run `fn(test[, done])` after each test case. * * @see https://mochajs.org/api/Mocha.Suite.html#afterEach */ - afterEach(title: string, fn?: Func): this; - + afterEach(fn?: Func | AsyncFunc): this; + /** * Run `fn(test[, done])` after each test case. * * @see https://mochajs.org/api/Mocha.Suite.html#afterEach */ - afterEach(title: string, fn?: AsyncFunc): this; - + afterEach(title: string, fn?: Func | AsyncFunc): this; + /** * Add a test `suite`. * * @see https://mochajs.org/api/Mocha.Suite.html#addSuite */ addSuite(suite: Suite): this; - + /** * Add a `test` to this suite. * * @see https://mochajs.org/api/Mocha.Suite.html#addTest */ addTest(test: Test): this; - + /** * Return the full title generated by recursively concatenating the parent's * full title. @@ -250,7 +194,7 @@ declare module Mocha { * @see https://mochajs.org/api/Mocha.Suite.html#.Suite#fullTitle */ fullTitle(): string; - + /** * Return the title path generated by recursively concatenating the parent's * title path. @@ -258,14 +202,14 @@ declare module Mocha { * @see https://mochajs.org/api/Mocha.Suite.html#.Suite#titlePath */ titlePath(): string[]; - + /** * Return the total number of tests. * * @see https://mochajs.org/api/Mocha.Suite.html#.Suite#total */ total(): number; - + /** * Iterates through each suite recursively to find all tests. Applies a * function in the format `fn(test)`. @@ -273,14 +217,14 @@ declare module Mocha { * @see https://mochajs.org/api/Mocha.Suite.html#eachTest */ eachTest(fn: (test: Test) => void): this; - + /** * This will run the root suite if we happen to be running in delayed mode. * * @see https://mochajs.org/api/Mocha.Suite.html#run */ run(): void; - + /** * Generic hook-creator. */ @@ -569,4 +513,4 @@ declare module Mocha { [key: string]: any; } -} \ No newline at end of file +} diff --git a/typings/index.d.ts b/typings/index.d.ts index 859ab6415..9ce324515 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1,4 +1,3 @@ -// Type definitions for CodeceptJS // Project: https://github.com/codeception/codeceptjs/ /// /// @@ -6,7 +5,17 @@ declare namespace CodeceptJS { type WithTranslation = T & - import("./utils").Translate; + import("./utils").Translate; + + type Cookie = { + name: string + value: string + } + + interface PageScrollPosition { + x: number, + y: number + } // Could get extended by user generated typings interface Methods extends ActorStatic {} @@ -28,7 +37,7 @@ declare namespace CodeceptJS { } // Types who are not be defined by JSDoc - type actor = ( + type actor = void }>( customSteps?: T & ThisType> ) => WithTranslation; @@ -46,14 +55,13 @@ declare namespace CodeceptJS { type LocatorOrString = string | ILocator | Locator; interface HookCallback { (args: SupportObject): void; } - interface Scenario extends IScenario { only: IScenario, skip: IScenario, todo: IScenario} + interface Scenario extends IScenario { only: IScenario, skip: IScenario, todo: IScenario} interface Feature extends IFeature { skip: IFeature } interface IData { Scenario: IScenario, only: { Scenario: IScenario } } interface IScenario { // Scenario.todo can be called only with a title. - (title: string): ScenarioConfig; - (title: string, callback: HookCallback): ScenarioConfig; + (title: string, callback?: HookCallback): ScenarioConfig; (title: string, opts: { [key: string]: any }, callback: HookCallback): ScenarioConfig; } interface IHook { (callback: HookCallback): void; } @@ -150,13 +158,13 @@ declare namespace Mocha { After: typeof After; } - interface Suite extends SuiteRunnable{ + interface Suite extends SuiteRunnable { tags: any[] comment: string feature: any } - interface Test extends Runnable{ + interface Test extends Runnable { tags: any[]; } } diff --git a/typings/tests/global-variables.types.ts b/typings/tests/global-variables.types.ts new file mode 100644 index 000000000..670c0a617 --- /dev/null +++ b/typings/tests/global-variables.types.ts @@ -0,0 +1,50 @@ +Feature() // $ExpectError +Scenario() // $ExpectError +Before() // $ExpectError +BeforeSuite() // $ExpectError +After() // $ExpectError +AfterSuite() // $ExpectError + +Feature('feature') // $ExpectType FeatureConfig + +Scenario('scenario') // $ExpectType ScenarioConfig +Scenario( + 'scenario', + {}, // $ExpectType {} + () => {} // $ExpectType () => void +) +Scenario( + 'scenario', + () => {} // $ExpectType () => void +) +const callback: CodeceptJS.HookCallback = () => {} +Scenario( + 'scenario', + callback // $ExpectType HookCallback +) +Scenario('scenario', + (args) => { + args // $ExpectType SupportObject + args.I // $ExpectType I + } +) + +Before((args) => { + args // $ExpectType SupportObject + args.I // $ExpectType I +}) + +BeforeSuite((args) => { + args // $ExpectType SupportObject + args.I // $ExpectType I +}) + +After((args) => { + args // $ExpectType SupportObject + args.I // $ExpectType I +}) + +AfterSuite((args) => { + args // $ExpectType SupportObject + args.I // $ExpectType I +}) diff --git a/typings/tests/helper.types.ts b/typings/tests/helper.types.ts new file mode 100644 index 000000000..1f02ecea7 --- /dev/null +++ b/typings/tests/helper.types.ts @@ -0,0 +1,46 @@ +// @TODO: Need tests arguments of protected methods + +class CustomClass extends Helper { + constructor(config: any) { + super( + config // $ExpectType any + ) + this.helpers // $ExpectType any + this.debug() // $ExpectError + this.debugSection() // $ExpectError + this.debugSection('[Section]') // $ExpectError + + this.debug('log') // $ExpectType void + this.debugSection('[Section]', 'log') // $ExpectType void + } + _failed() {} // $ExpectType () => void + _finishTest() {} // $ExpectType () => void + _init() {} // $ExpectType () => void + _passed() {} // $ExpectType () => void + _setConfig() {} // $ExpectType () => void + _useTo() {} // $ExpectType () => void + _validateConfig() {} // $ExpectType () => void + _before() {} // $ExpectType () => void + _beforeStep() {} // $ExpectType () => void + _beforeSuite() {} // $ExpectType () => void + _after() {} // $ExpectType () => void + _afterStep() {} // $ExpectType () => void + _afterSuite() {} // $ExpectType () => void +} + +const customClass = new Helper({}) + +customClass._failed() // $ExpectError +customClass._finishTest() // $ExpectError +customClass._init() // $ExpectError +customClass._passed() // $ExpectError +customClass._setConfig() // $ExpectError +customClass._validateConfig() // $ExpectError +customClass._before() // $ExpectError +customClass._beforeStep() // $ExpectError +customClass._beforeSuite() // $ExpectError +customClass._after() // $ExpectError +customClass._afterStep() // $ExpectError +customClass._afterSuite() // $ExpectError + +customClass._useTo() // $ExpectType void diff --git a/typings/tests/helpers/WebDriverIO.types.ts b/typings/tests/helpers/WebDriverIO.types.ts new file mode 100644 index 000000000..f544d38af --- /dev/null +++ b/typings/tests/helpers/WebDriverIO.types.ts @@ -0,0 +1,439 @@ +const wd = new CodeceptJS.WebDriver() + +const str = 'text' +const num = 1 + +wd.amOnPage() // $ExpectError +wd.amOnPage('') // $ExpectType void + +wd.click() // $ExpectError +wd.click('div') // $ExpectType void +wd.click({ css: 'div' }) +wd.click({ xpath: '//div' }) +wd.click({ name: 'div' }) +wd.click({ id: 'div' }) +wd.click({ android: 'div' }) +wd.click({ ios: 'div' }) +wd.click(locate('div')) +wd.click('div', 'body') +wd.click('div', locate('div')) +wd.click('div', { css: 'div' }) +wd.click('div', { xpath: '//div' }) +wd.click('div', { name: '//div' }) +wd.click('div', { id: '//div' }) +wd.click('div', { android: '//div' }) +wd.click('div', { ios: '//div' }) + +wd.forceClick() // $ExpectError +wd.forceClick('div') // $ExpectType void +wd.forceClick({ css: 'div' }) +wd.forceClick({ xpath: '//div' }) +wd.forceClick({ name: 'div' }) +wd.forceClick({ id: 'div' }) +wd.forceClick({ android: 'div' }) +wd.forceClick({ ios: 'div' }) +wd.forceClick(locate('div')) +wd.forceClick('div', 'body') +wd.forceClick('div', locate('div')) +wd.forceClick('div', { css: 'div' }) +wd.forceClick('div', { xpath: '//div' }) +wd.forceClick('div', { name: '//div' }) +wd.forceClick('div', { id: '//div' }) +wd.forceClick('div', { android: '//div' }) +wd.forceClick('div', { ios: '//div' }) + +wd.doubleClick() // $ExpectError +wd.doubleClick('div') // $ExpectType void +wd.doubleClick({ css: 'div' }) +wd.doubleClick({ xpath: '//div' }) +wd.doubleClick({ name: 'div' }) +wd.doubleClick({ id: 'div' }) +wd.doubleClick({ android: 'div' }) +wd.doubleClick({ ios: 'div' }) +wd.doubleClick(locate('div')) +wd.doubleClick('div', 'body') +wd.doubleClick('div', locate('div')) +wd.doubleClick('div', { css: 'div' }) +wd.doubleClick('div', { xpath: '//div' }) +wd.doubleClick('div', { name: '//div' }) +wd.doubleClick('div', { id: '//div' }) +wd.doubleClick('div', { android: '//div' }) +wd.doubleClick('div', { ios: '//div' }) + +wd.rightClick() // $ExpectError +wd.rightClick('div') // $ExpectType void +wd.rightClick({ css: 'div' }) +wd.rightClick({ xpath: '//div' }) +wd.rightClick({ name: 'div' }) +wd.rightClick({ id: 'div' }) +wd.rightClick({ android: 'div' }) +wd.rightClick({ ios: 'div' }) +wd.rightClick(locate('div')) +wd.rightClick('div', 'body') +wd.rightClick('div', locate('div')) +wd.rightClick('div', { css: 'div' }) +wd.rightClick('div', { xpath: '//div' }) +wd.rightClick('div', { name: '//div' }) +wd.rightClick('div', { id: '//div' }) +wd.rightClick('div', { android: '//div' }) +wd.rightClick('div', { ios: '//div' }) + +wd.fillField() // $ExpectError +wd.fillField('div') // $ExpectError +wd.fillField('div', str) // $ExpectType void +wd.fillField({ css: 'div' }, str) +wd.fillField({ xpath: '//div' }, str) +wd.fillField({ name: 'div' }, str) +wd.fillField({ id: 'div' }, str) +wd.fillField({ android: 'div' }, str) +wd.fillField({ ios: 'div' }, str) +wd.fillField(locate('div'), str) + +wd.appendField() // $ExpectError +wd.appendField('div') // $ExpectError +wd.appendField('div', str) // $ExpectType void +wd.appendField({ css: 'div' }, str) +wd.appendField({ xpath: '//div' }, str) +wd.appendField({ name: 'div' }, str) +wd.appendField({ id: 'div' }, str) +wd.appendField({ android: 'div' }, str) +wd.appendField({ ios: 'div' }, str) +wd.appendField(locate('div'), str) + +wd.clearField() // $ExpectError +wd.clearField('div') +wd.clearField({ css: 'div' }) +wd.clearField({ xpath: '//div' }) +wd.clearField({ name: 'div' }) +wd.clearField({ id: 'div' }) +wd.clearField({ android: 'div' }) +wd.clearField({ ios: 'div' }) + +wd.selectOption() // $ExpectError +wd.selectOption('div') // $ExpectError +wd.selectOption('div', str) // $ExpectType void + +wd.attachFile() // $ExpectError +wd.attachFile('div') // $ExpectError +wd.attachFile('div', str) // $ExpectType void + +wd.checkOption() // $ExpectError +wd.checkOption('div') // $ExpectType void + +wd.uncheckOption() // $ExpectError +wd.uncheckOption('div') // $ExpectType void + +wd.seeInTitle() // $ExpectError +wd.seeInTitle(str) // $ExpectType void + +wd.seeTitleEquals() // $ExpectError +wd.seeTitleEquals(str) // $ExpectType void + +wd.dontSeeInTitle() // $ExpectError +wd.dontSeeInTitle(str) // $ExpectType void + +wd.see() // $ExpectError +wd.see(str) // $ExpectType void +wd.see(str, 'div') // $ExpectType void + +wd.dontSee() // $ExpectError +wd.dontSee(str) // $ExpectType void +wd.dontSee(str, 'div') // $ExpectType void + +wd.seeTextEquals() // $ExpectError +wd.seeTextEquals(str) // $ExpectType void +wd.seeTextEquals(str, 'div') // $ExpectType void + +wd.seeInField() // $ExpectError +wd.seeInField('div') // $ExpectError +wd.seeInField('div', str) // $ExpectType void + +wd.dontSeeInField() // $ExpectError +wd.dontSeeInField('div') // $ExpectError +wd.dontSeeInField('div', str) // $ExpectType void + +wd.seeCheckboxIsChecked() // $ExpectError +wd.seeCheckboxIsChecked('div') // $ExpectType void + +wd.dontSeeCheckboxIsChecked() // $ExpectError +wd.dontSeeCheckboxIsChecked('div') // $ExpectType void + +wd.seeElement() // $ExpectError +wd.seeElement('div') // $ExpectType void + +wd.dontSeeElement() // $ExpectError +wd.dontSeeElement('div') // $ExpectType void + +wd.seeElementInDOM() // $ExpectError +wd.seeElementInDOM('div') // $ExpectType void + +wd.dontSeeElementInDOM() // $ExpectError +wd.dontSeeElementInDOM('div') // $ExpectType void + +wd.seeInSource() // $ExpectError +wd.seeInSource(str) // $ExpectType void + +wd.dontSeeInSource() // $ExpectError +wd.dontSeeInSource(str) // $ExpectType void + +wd.seeNumberOfElements() // $ExpectError +wd.seeNumberOfElements('div') // $ExpectError +wd.seeNumberOfElements('div', num) // $ExpectType void + +wd.seeNumberOfVisibleElements() // $ExpectError +wd.seeNumberOfVisibleElements('div') // $ExpectError +wd.seeNumberOfVisibleElements('div', num) // $ExpectType void + +wd.seeCssPropertiesOnElements() // $ExpectError +wd.seeCssPropertiesOnElements('div') // $ExpectError +wd.seeCssPropertiesOnElements('div', str) // $ExpectType void + +wd.seeAttributesOnElements() // $ExpectError +wd.seeAttributesOnElements('div') // $ExpectError +wd.seeAttributesOnElements('div', str) // $ExpectType void + +wd.seeInCurrentUrl() // $ExpectError +wd.seeInCurrentUrl(str) // $ExpectType void + +wd.seeCurrentUrlEquals() // $ExpectError +wd.seeCurrentUrlEquals(str) // $ExpectType void + +wd.dontSeeInCurrentUrl() // $ExpectError +wd.dontSeeInCurrentUrl(str) // $ExpectType void + +wd.dontSeeCurrentUrlEquals() // $ExpectError +wd.dontSeeCurrentUrlEquals(str) // $ExpectType void + +wd.executeScript() // $ExpectError +wd.executeScript(str) // $ExpectType Promise +wd.executeScript(() => {}) // $ExpectType Promise +wd.executeScript(() => {}, {}) // $ExpectType Promise + +wd.executeAsyncScript() // $ExpectError +wd.executeAsyncScript(str) // $ExpectType Promise +wd.executeAsyncScript(() => {}) // $ExpectType Promise +wd.executeAsyncScript(() => {}, {}) // $ExpectType Promise + +wd.scrollIntoView() // $ExpectError +wd.scrollIntoView('div') // $ExpectError +wd.scrollIntoView('div', {behavior: "auto", block: "center", inline: "center"}) + +wd.scrollTo() // $ExpectError +wd.scrollTo('div') // $ExpectType void +wd.scrollTo('div', num, num) // $ExpectType void + +wd.moveCursorTo() // $ExpectError +wd.moveCursorTo('div') // $ExpectType void +wd.moveCursorTo('div', num, num) // $ExpectType void + +wd.saveScreenshot() // $ExpectError +wd.saveScreenshot(str) // $ExpectType void +wd.saveScreenshot(str, true) // $ExpectType void + +wd.setCookie() // $ExpectError +wd.setCookie({name: str, value: str}) // $ExpectType void +wd.setCookie([{name: str, value: str}]) // $ExpectType void + +wd.clearCookie() // $ExpectType void +wd.clearCookie(str) // $ExpectType void + +wd.seeCookie() // $ExpectError +wd.seeCookie(str) // $ExpectType void + +wd.acceptPopup() // $ExpectType void + +wd.cancelPopup() // $ExpectType void + +wd.seeInPopup() // $ExpectError +wd.seeInPopup(str) // $ExpectType void + +wd.pressKeyDown() // $ExpectError +wd.pressKeyDown(str) // $ExpectType void + +wd.pressKeyUp() // $ExpectError +wd.pressKeyUp(str) // $ExpectType void + +wd.pressKey() // $ExpectError +wd.pressKey(str) // $ExpectType void + +wd.type() // $ExpectError +wd.type(str) // $ExpectType void + +wd.resizeWindow() // $ExpectError +wd.resizeWindow(num) // $ExpectError +wd.resizeWindow(num, num) // $ExpectType void + +wd.dragAndDrop() // $ExpectError +wd.dragAndDrop('div') // $ExpectError +wd.dragAndDrop('div', 'div') // $ExpectType void + +wd.dragSlider() // $ExpectError +wd.dragSlider('div', num) // $ExpectType void + +wd.switchToWindow() // $ExpectError +wd.switchToWindow(str) // $ExpectType void + +wd.closeOtherTabs() // $ExpectType void + +wd.wait() // $ExpectError +wd.wait(num) // $ExpectType void + +wd.waitForEnabled() // $ExpectError +wd.waitForEnabled('div') // $ExpectType void +wd.waitForEnabled('div', num) // $ExpectType void + +wd.waitForElement() // $ExpectError +wd.waitForElement('div') // $ExpectType void +wd.waitForElement('div', num) // $ExpectType void + +wd.waitForClickable() // $ExpectError +wd.waitForClickable('div') // $ExpectType void +wd.waitForClickable('div', num) // $ExpectType void + +wd.waitForVisible() // $ExpectError +wd.waitForVisible('div') // $ExpectType void +wd.waitForVisible('div', num) // $ExpectType void + +wd.waitForInvisible() // $ExpectError +wd.waitForInvisible('div') // $ExpectType void +wd.waitForInvisible('div', num) // $ExpectType void + +wd.waitToHide() // $ExpectError +wd.waitToHide('div') // $ExpectType void +wd.waitToHide('div', num) // $ExpectType void + +wd.waitForDetached() // $ExpectError +wd.waitForDetached('div') // $ExpectType void +wd.waitForDetached('div', num) // $ExpectType void + +wd.waitForFunction() // $ExpectError +wd.waitForFunction('div') // $ExpectType void +wd.waitForFunction(() => {}) // $ExpectType void +wd.waitForFunction(() => {}, [num], num) // $ExpectType void +wd.waitForFunction(() => {}, [str], num) // $ExpectType void + +wd.waitInUrl() // $ExpectError +wd.waitInUrl(str) // $ExpectType void +wd.waitInUrl(str, num) // $ExpectType void + +wd.waitForText() // $ExpectError +wd.waitForText(str) // $ExpectType void +wd.waitForText(str, num, str) // $ExpectType void + +wd.waitForValue() // $ExpectError +wd.waitForValue(str) // $ExpectError +wd.waitForValue(str, str) // $ExpectType void +wd.waitForValue(str, str, num) // $ExpectType void + +wd.waitNumberOfVisibleElements() // $ExpectError +wd.waitNumberOfVisibleElements('div') // $ExpectError +wd.waitNumberOfVisibleElements(str, num) // $ExpectType void +wd.waitNumberOfVisibleElements(str, num, num) // $ExpectType void + +wd.waitUrlEquals() // $ExpectError +wd.waitUrlEquals(str) // $ExpectType void +wd.waitUrlEquals(str, num) // $ExpectType void + +wd.waitUntil() // $ExpectError +wd.waitUntil(() => {}) // $ExpectType void +wd.waitUntil(str) // $ExpectType void +wd.waitUntil(str, num, str, num) // $ExpectType void +wd.waitUntil(() => {}, num, str, num) // $ExpectType void + +wd.switchTo() // $ExpectType void +wd.switchTo('div') // $ExpectType void + +wd.switchToNextTab(num, num) // $ExpectType void + +wd.switchToPreviousTab(num, num) // $ExpectType void + +wd.closeCurrentTab() // $ExpectType void + +wd.openNewTab() // $ExpectType void + +wd.refreshPage() // $ExpectType void + +wd.scrollPageToTop() // $ExpectType void + +wd.scrollPageToBottom() // $ExpectType void + +wd.setGeoLocation() // $ExpectError +wd.setGeoLocation(num) // $ExpectError +wd.setGeoLocation(num, num) // $ExpectType void +wd.setGeoLocation(num, num, num) // $ExpectType void + +wd.dontSeeCookie() // $ExpectError +wd.dontSeeCookie(str) // $ExpectType void + +wd.dragAndDrop(); // $ExpectError +wd.dragAndDrop('#dragHandle'); // $ExpectError +wd.dragAndDrop('#dragHandle', '#container'); + +wd.grabTextFromAll() // $ExpectError +wd.grabTextFromAll('div') // $ExpectType Promise + +wd.grabTextFrom() // $ExpectError +wd.grabTextFrom('div') // $ExpectType Promise + +wd.grabHTMLFromAll() // $ExpectError +wd.grabHTMLFromAll('div') // $ExpectType Promise + +wd.grabHTMLFrom() // $ExpectError +wd.grabHTMLFrom('div') // $ExpectType Promise + +wd.grabValueFromAll() // $ExpectError +wd.grabValueFromAll('div') // $ExpectType Promise + +wd.grabValueFrom() // $ExpectError +wd.grabValueFrom('div') // $ExpectType Promise + +wd.grabCssPropertyFromAll() // $ExpectError +wd.grabCssPropertyFromAll('div') // $ExpectError +wd.grabCssPropertyFromAll('div', 'color') // $ExpectType Promise + +wd.grabCssPropertyFrom() // $ExpectError +wd.grabCssPropertyFrom('div') // $ExpectError +wd.grabCssPropertyFrom('div', 'color') // $ExpectType Promise + +wd.grabAttributeFromAll() // $ExpectError +wd.grabAttributeFromAll('div') // $ExpectError +wd.grabAttributeFromAll('div', 'style') // $ExpectType Promise + +wd.grabAttributeFrom() // $ExpectError +wd.grabAttributeFrom('div') // $ExpectError +wd.grabAttributeFrom('div', 'style') // $ExpectType Promise + +wd.grabTitle() // $ExpectType Promise + +wd.grabSource() // $ExpectType Promise + +wd.grabBrowserLogs() // $ExpectType Promise | undefined + +wd.grabCurrentUrl() // $ExpectType Promise + +wd.grabNumberOfVisibleElements() // $ExpectError +wd.grabNumberOfVisibleElements('div') // $ExpectType Promise + +wd.grabCookie(); // $ExpectType Promise | Promise +wd.grabCookie('name'); // $ExpectType Promise | Promise + +wd.grabPopupText() // $ExpectType Promise + +wd.grabAllWindowHandles() // $ExpectType Promise +wd.grabCurrentWindowHandle() // $ExpectType Promise + +wd.grabNumberOfOpenTabs() // $ExpectType Promise + +const psp = wd.grabPageScrollPosition() // $ExpectType Promise +psp.then( + result => { + result.x // $ExpectType number + result.y // $ExpectType number + } +) + +wd.grabGeoLocation() // $ExpectType Promise<{ latitude: number; longitude: number; altitude: number; }> + +wd.grabElementBoundingRect(); // $ExpectError +wd.grabElementBoundingRect('h3'); // $ExpectType Promise | Promise +wd.grabElementBoundingRect('h3', 'width') // $ExpectType Promise | Promise diff --git a/typings/tsconfig.json b/typings/tsconfig.json new file mode 100644 index 000000000..2ec0512ec --- /dev/null +++ b/typings/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es2018", + "lib": ["es2018", "DOM"], + "esModuleInterop": true, + "module": "commonjs", + "strictNullChecks": true, + "noImplicitAny": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitThis": true, + "strictFunctionTypes": true, + "skipLibCheck": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "include": [ + "**/*.ts" + ] +} diff --git a/typings/tslint.json b/typings/tslint.json new file mode 100644 index 000000000..3b4ce5d1f --- /dev/null +++ b/typings/tslint.json @@ -0,0 +1,22 @@ +{ + "extends": "dtslint/dtslint.json", + "rules": { + "semicolon": false, + "no-empty-interface": false, + "interface-name": false, + "jsdoc-format": false, + "max-line-length": false, + "no-single-declare-module": false, + "no-unnecessary-qualifier": false, + "interface-over-type-literal": false, + "no-var-keyword": false, + "no-unnecessary-class": false, + "array-type": false, + "trim-file": false, + "no-consecutive-blank-lines": false + }, + "linterOptions": { + "exclude": [ + ] + } +} diff --git a/typings/utils.d.ts b/typings/utils.d.ts index 0a1804aca..42e77fb0c 100644 --- a/typings/utils.d.ts +++ b/typings/utils.d.ts @@ -1,5 +1,5 @@ -type ValueOf = T[keyof T] -type KeyValueTupleToObject = { +export type ValueOf = T[keyof T] +export type KeyValueTupleToObject = { [K in T[0]]: Extract[1] } export type Translate> = KeyValueTupleToObject