From e7c6a961a7108f625e196e5fa1fa5397c872b4ea Mon Sep 17 00:00:00 2001 From: Lukas Beranek Date: Mon, 20 May 2019 21:48:48 +0200 Subject: [PATCH] [nightwatch] update to v1 and allow types for pages and commands (#35387) --- types/nightwatch/index.d.ts | 3033 ++++++++++++++------------ types/nightwatch/nightwatch-tests.ts | 298 ++- 2 files changed, 1928 insertions(+), 1403 deletions(-) diff --git a/types/nightwatch/index.d.ts b/types/nightwatch/index.d.ts index ae5fc34d36..98c20ba16c 100644 --- a/types/nightwatch/index.d.ts +++ b/types/nightwatch/index.d.ts @@ -1,13 +1,11 @@ -// Type definitions for nightwatch 0.9 +// Type definitions for nightwatch 1.1 // Project: http://nightwatchjs.org // Definitions by: Rahul Kavalapara // Connor Schlesiger // Clayton Astrom +// Lukas Beranek // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -export interface NightwatchCustomPageObjects { - page: {[name: string]: () => EnhancedPageObject}; -} +// TypeScript Version: 2.3 export interface NightwatchDesiredCapabilities { /** @@ -199,6 +197,43 @@ export interface NightwatchOptions { test_runner?: string | NightwatchTestRunner; } +export interface NightwatchGlobals { + /** + * this controls whether to abort the test execution when an assertion failed and skip the rest + * it's being used in waitFor commands and expect assertions + * @default true + */ + abortOnAssertionFailure?: boolean; + + /** + * this will overwrite the default polling interval (currently 500ms) for waitFor commands + * and expect assertions that use retry + * @default 300 + */ + waitForConditionPollInterval?: number; + + /** + * default timeout value in milliseconds for waitFor commands and implicit waitFor value for + * expect assertions + * @default 5000 + */ + waitForConditionTimeout?: number; + + /** + * this will cause waitFor commands on elements to throw an error if multiple + * elements are found using the given locate strategy and selector + * @default true + */ + throwOnMultipleElementsReturned?: boolean; + + /** + * controls the timeout time for async hooks. Expects the done() callback to be invoked within this time + * or an error is thrown + * @default 10000 + */ + asyncHookTimeout?: number; +} + export interface NightwatchSeleniumOptions { /** * Whether or not to manage the selenium process automatically. @@ -311,7 +346,7 @@ export interface NightwatchTestSettingGeneric { /** * An object which will be made available within the test and can be overwritten per environment. Example:"globals" : { "myGlobal" : "some_global" } */ - globals: any; + globals: NightwatchGlobals; /** * An array of folders or file patterns to be skipped (relative to the main source folder). @@ -407,7 +442,6 @@ export interface NightwatchTestSettings { export interface Expect extends NightwatchLanguageChains, NightwatchBrowser { /** * Returns the DOM Element - * @param property: Css / Id property of the DOM element */ element(property: string): this; @@ -416,8 +450,10 @@ export interface Expect extends NightwatchLanguageChains, NightwatchBrowser { * The targets can be an attribute value, the element's inner text and a css property. */ equal(value: string): this; + equals(value: string): this; contain(value: string): this; - match(value: string): this; + contains(value: string): this; + match(value: string | RegExp): this; /** * Negates any of assertions following in the chain. @@ -429,30 +465,23 @@ export interface Expect extends NightwatchLanguageChains, NightwatchBrowser { * before or after can be chained to any assertion and thus adding retry capability. You can change the polling interval by defining * a waitForConditionPollInterval property (in milliseconds) as a global property in your nightwatch.json or in * your external globals file. Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds). - * @param value: Number of milliseconds to wait to perform and operation of check */ before(value: number): this; after(value: number): this; /** * Checks if the type (i.e. tag name) of a specified element is of an expected value. - * @param value: The expected type - * @param message: Optional log message to display in the output. If missing, one is displayed by default. */ a(value: string, message?: string): this; an(value: string, message?: string): this; /** * Checks if a given attribute of an element exists and optionally if it has the expected value. - * @param attribute: The attribute name - * @param message: Optional log message to display in the output. If missing, one is displayed by default. */ attribute(name: string, message?: string): this; /** * Checks a given css property of an element exists and optionally if it has the expected value. - * @param property: The css property name - * @param message: Optional log message to display in the output. If missing, one is displayed by default. */ css(property: string, message?: string): this; @@ -487,155 +516,240 @@ export interface Expect extends NightwatchLanguageChains, NightwatchBrowser { visible: this; } -export interface NightwatchAssertions extends NightwatchBrowser { +export interface NightwatchAssertions extends NightwatchCommonAssertions, NightwatchCustomAssertions { +} + +export interface NightwatchCommonAssertions { /** * Checks if the given attribute of an element contains the expected value. - * @param selector: The selector (CSS / Xpath) used to locate the element. - * @param attribute: The attribute name - * @param expected: The expected contained value of the attribute to check. - * @param message: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.attributeContains('#someElement', 'href', 'google.com'); + * }; + * ``` */ - attributeContains(selector: string, attribute: string, expected: string, message?: string): this; + attributeContains(selector: string, attribute: string, expected: string, message?: string): NightwatchAPI; /** * Checks if the given attribute of an element has the expected value. - * @param cssSelector: The CSS selector used to locate the element. - * @param attribute: The attribute name - * @param expected: The expected value of the attribute to check. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.attributeEquals('body', 'data-attr', 'some value'); + * }; + * ``` */ - attributeEquals(cssSelector: string, attribute: string, expected: string, msg?: string): this; + attributeEquals(selector: string, attribute: string, expected: string, message?: string): NightwatchAPI; /** * Checks if the given element contains the specified text. - * @param cssSelector: The CSS selector used to locate the element. - * @param expectedText: The text to look for. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.containsText('#main', 'The Night Watch'); + * }; + * ``` */ - containsText(cssSelector: string, expectedText: string, msg?: string): this; + containsText(selector: string, expectedText: string, message?: string): NightwatchAPI; /** * Checks if the given element has the specified CSS class. - * @param cssSelector: The CSS selector used to locate the element. - * @param className: The CSS class to look for. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.cssClassPresent('#main', 'container'); + * }; + * ``` */ - cssClassPresent(cssSelector: string, className: string, msg?: string): this; - - /** - * Checks if the given element does not have the specified CSS class. - * @param cssSelector: The CSS selector used to locate the element. - * @param className: The CSS class to look for. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. - */ - cssClassNotPresent(cssSelector: string, className: string, msg?: string): this; - - /** - * Checks if the specified css property of a given element has the expected value. - * @param cssSelector: The CSS selector used to locate the element. - * @param cssProperty: The CSS property. - * @param expected: The expected value of the css property to check. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. - */ - cssProperty(cssSelector: string, cssProperty: string, expected: string | number, msg?: string): this; - - deepEqual(value: any, expected: any, message?: string): this; - - deepStrictEqual(value: any, expected: any, message?: string): this; - - doesNotThrow(value: any, expected: any, message?: string): this; + cssClassPresent(selector: string, className: string, message?: string): NightwatchAPI; /** * Checks if the given element exists in the DOM. - * @param cssSelector: The CSS selector used to locate the element. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.elementNotPresent(".should_not_exist"); + * }; + * ``` */ - elementPresent(cssSelector: string, msg?: string): this; + cssClassNotPresent(selector: string, className: string, msg?: string): NightwatchAPI; /** - * Checks if the given element does not exist in the DOM. - * @param cssSelector: The CSS selector used to locate the element. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * Checks if the specified css property of a given element has the expected value. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.cssProperty('#main', 'display', 'block'); + * }; + * ``` */ - elementNotPresent(cssSelector: string, msg?: string): this; + cssProperty(selector: string, cssProperty: string, expected: string | number, msg?: string): NightwatchAPI; - equal(value: any, expected: any, message?: string): this; + deepEqual(value: any, expected: any, message?: string): NightwatchAPI; - fail(actual?: any, expected?: any, message?: string, operator?: string): this; + deepStrictEqual(value: any, expected: any, message?: string): NightwatchAPI; + + doesNotThrow(value: any, expected: any, message?: string): NightwatchAPI; + + /** + * Checks if the given element exists in the DOM. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.elementPresent("#main"); + * }; + * ``` + */ + elementPresent(selector: string, msg?: string): NightwatchAPI; + + /** + * Checks if the given element exists in the DOM. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.elementNotPresent(".should_not_exist"); + * }; + * ``` + */ + elementNotPresent(selector: string, msg?: string): NightwatchAPI; + + equal(value: any, expected: any, message?: string): NightwatchAPI; + + fail(actual?: any, expected?: any, message?: string, operator?: string): NightwatchAPI; /** * Checks if the given element is not visible on the page. - * @param cssSelector: The CSS selector used to locate the element. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.hidden(".should_not_be_visible"); + * }; + * ``` */ - hidden(cssSelector: string, msg?: string): this; + hidden(selector: string, msg?: string): NightwatchAPI; - ifError(value: any, message?: string): this; + ifError(value: any, message?: string): NightwatchAPI; - notDeepEqual(actual: any, expected: any, message?: string): this; + notDeepEqual(actual: any, expected: any, message?: string): NightwatchAPI; - notDeepStrictEqual(value: any, message?: string): this; + notDeepStrictEqual(value: any, message?: string): NightwatchAPI; - notEqual(actual: any, expected: any, message?: string): this; + notEqual(actual: any, expected: any, message?: string): NightwatchAPI; - notStrictEqual(value: any, expected: any, message?: string): this; + notStrictEqual(value: any, expected: any, message?: string): NightwatchAPI; - ok(actual: boolean, message?: string): this; + ok(actual: boolean, message?: string): NightwatchAPI; - strictEqual(value: any, expected: any, message?: string): this; + strictEqual(value: any, expected: any, message?: string): NightwatchAPI; - throws(fn: () => void, msg?: string): this; + throws(fn: () => void, message?: string): NightwatchAPI; + + /** + * Checks if the page title equals the given value. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.title("Nightwatch.js"); + * }; + * ``` + */ + title(expected: string, message?: string): NightwatchAPI; + + /** + * Checks if the page title equals the given value. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.title("Nightwatch.js"); + * }; + * ``` + */ + titleContains(expected: string, message?: string): NightwatchAPI; /** * Checks if the current URL contains the given value. - * @param expectedText: The value expected to exist within the current URL. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.urlContains('google'); + * }; + * ``` */ - urlContains(expectedText: string, msg?: string): this; + urlContains(expectedText: string, message?: string): NightwatchAPI; /** * Checks if the current url equals the given value. - * @param expected: The expected url. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.urlEquals('https://www.google.com'); + * }; + * ``` */ - urlEquals(expected: string, msg?: string): this; + urlEquals(expected: string, message?: string): NightwatchAPI; /** * Checks if the given form element's value equals the expected value. - * @param cssSelector: The CSS selector used to locate the element. - * @param expectedText: The expected text. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.value("form.login input[type=text]", "username"); + * }; + * ``` */ - value(cssSelector: string, expectedText: string, msg?: string): this; + value(selector: string, expectedText: string, message?: string): NightwatchAPI; /** * Checks if the given form element's value contains the expected value. - * @param cssSelector: The CSS selector used to locate the element. - * @param expectedText: The expected text. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.valueContains("form.login input[type=text]", "username"); + * }; + * ``` */ - valueContains(cssSelector: string, expectedText: string, msg?: string): this; + valueContains(selector: string, expectedText: string, message?: string): NightwatchAPI; /** * Checks if the given element is visible on the page. - * @param cssSelector: The CSS selector used to locate the element. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. + * + * ``` + * this.demoTest = function (client) { + * browser.assert.visible(".should_be_visible"); + * }; + * ``` */ - visible(cssSelector: string, msg?: string): this; + visible(selector: string, message?: string): NightwatchAPI; NightwatchAssertionsError: NightwatchAssertionsError; } export interface NightwatchTypedCallbackResult { - status: number; + status: 0; value: T; state: Error | string; } - -// tslint:disable-next-line:no-empty-interface -export interface NightwatchCallbackResult extends NightwatchTypedCallbackResult { +export interface NightwatchCallbackResultError { + status: 1; // we cannot use `number` so giving it a "symbolic" value allows to disjoint the union + value: { + message: string; + screen: string; + class: string; + stackTrace: Array<{ + fileName: string; + lineNumber: number; + className: string; + methodName: string; + }>; + }; + state: Error | string; } +export type NightwatchCallbackResult = + | NightwatchTypedCallbackResult + | NightwatchCallbackResultError; + export interface NightwatchLogEntry { /** * The log entry message. @@ -650,7 +764,9 @@ export interface NightwatchLogEntry { /** * Severity level */ - level: string; + level: "SEVERE" | "WARNING" | "INFO" | "DEBUG"; + + source?: string; } export interface NightwatchKeys { @@ -776,344 +892,14 @@ export interface NightwatchKeys { "COMMAND": string; } -export interface NightwatchAPI extends SharedFunctions { +export interface NightwatchAPI extends SharedCommands, WebDriverProtocol, NightwatchCustomCommands { assert: NightwatchAssertions; - expect: Expect; - verify: NightwatchAssertions; - /** - * Close the current window. This can be useful when you're working with multiple windows open (e.g. an OAuth login). Uses window protocol command. - * - * Usage: - * ``` - * this.demoTest = function (client) { - * client.closeWindow(); - * }; - * ``` - * @param callback: Optional callback function to be called when the command finishes. - */ - closeWindow(callback?: () => void): this; - - /** - * Delete the cookie with the given name. This command is a no-op if there is no such cookie visible to the current page. - * - * Usage: - * ``` - * this.demoTest = function(browser) { - * browser.deleteCookie("test_cookie", function() { - * // do something more in here - * }); - * } - * ``` - * @param The: name of the cookie to delete. - * @param callback: Optional callback function to be called when the command finishes. - */ - deleteCookie(The: string, callback?: () => void): this; - - /** - * Delete all cookies visible to the current page. - * - * Usage: - * ``` - * this.demoTest = function(browser) { - * browser.deleteCookies(function() { - * // do something more in here - * }); - * } - * ``` - * @param callback: Optional callback function to be called when the command finishes. - */ - deleteCookies(callback?: () => void): this; - - /** - * Ends the session. Uses session protocol command. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.end(); - * }; - * ``` - * @param callback: Optional callback function to be called when the command finishes. - */ - end(callback?: () => void): this; - - /** - * Retrieve a single cookie visible to the current page. The cookie is returned as a cookie JSON object, as defined here. - * Uses cookie protocol command. - * - * Usage: - * ``` - * this.demoTest = function(browser) { - * browser.getCookie(name, function callback(result) { - * this.assert.equal(result.value, '123456'); - * this.assert.equals(result.name, 'test_cookie'); - * }); - * } - * ``` - * @param name: The cookie name - * @param callback: The callback function which will receive the response as an argument. - * @returns The cookie object as a selenium cookie JSON object or null if the cookie wasn't found. - */ - getCookie(name: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; - - /** - * Retrieve all cookies visible to the current page. The cookies are returned as an array of cookie JSON object, - * as defined here. Uses cookie protocol command. - * - * Usage: - * ``` - * this.demoTest = function(browser) { - * browser.getCookies(function callback(result) { - * this.assert.equal(result.value.length, 1); - * this.assert.equals(result.value[0].name, 'test_cookie'); - * }); - * } - * ``` - * @param callback: The callback function which will receive the response as an argument. - * @returns A list of cookies - */ - getCookies(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; - - /** - * Gets a log from selenium - * - * Usage: - * ``` - * this.demoTest = function(client) { - * this.getLog('browser', function(logEntriesArray) { - * console.log('Log length: ' + logEntriesArray.length); - * logEntriesArray.forEach(function(log) { - * console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message); - * }); - * }); - * }; - * ``` - * @param typestring: Log type to request - * @param callback: Optional callback function to be called when the command finishes. - */ - getLog(typestring: string, callback?: (log: NightwatchLogEntry[]) => void): this; - - /** - * Gets the available log types - * - * Usage: - * ``` - * this.demoTest = function(client) { - * this.getLogTypes(function(typesArray) { - * console.log(typesArray); - * }); - * }; - * ``` - * @param callback: Optional callback function to be called when the command finishes. - * @returns Available log types - */ - getLogTypes(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Returns the title of the current page. Uses title protocol command. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.getTitle(function(title) { - * this.assert.equal(typeof title, 'string'); - * this.assert.equal(title, 'nightwatch.js'); - * }); - * }; - * ``` - * @param callback: Optional callback function to be called when the command finishes. - * @returns The page title. - */ - getTitle(callback?: (this: NightwatchAPI, result?: string) => void): this; - - /** - * This command is an alias to url and also a convenience method when called without any arguments in the sense that it performs a call to .url() with passing the value of launch_url - * field from the settings file. Uses url protocol command. - * - * Usage: - * ``` - * this.demoTest = function (client) { - * client.init(); - * }; - * ``` - * @param url: Url to navigate to. - */ - init(url?: string): this; - - /** - * Utility command to load an external script into the page specified by url. - * - * Usage: - * ``` - * this.demoTest = function(client) { - * this.injectScript("{script-url}", function() { - * // we're all done here. - * }); - * }; - * ``` - * @param scriptUrl: The script file url - * @param id: Dom element id to be set on the script tag. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The newly created script tag. - */ - injectScript(scriptUrl: string, id?: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Utility command to test if the log type is available - * - * Usage: - * ``` - * this.demoTest = function(browser) { - * browser.isLogAvailable('browser', function(isAvailable) { - * // do something more in here - * }); - * } - * ``` - * @param typeString: Type of log to test - * @param callback: Optional callback function to be called when the command finishes. - */ - isLogAvailable(typeString: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Maximizes the current window. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.maximizeWindow(); - * }; - * ``` - * @param callback: Optional callback function to be called when the command finishes. - */ - maximizeWindow(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Suspends the test for the given time in milliseconds. If the milliseconds argument is missing it will suspend the test indefinitely - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.pause(1000); - * // or suspend indefinitely - * browser.pause(); - * }; - * ``` - * @param ms: Optional - The number of milliseconds to wait. - * @param callback: Optional callback function to be called when the command finishes. - */ - pause(ms?: number, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * A simple perform command which allows access to the "api" in a callback. Can be useful if you want to read variables set by other commands. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * var elementValue; - * browser - * .getValue('.some-element', function(result) { - * elementValue = result.value; - * }) - * // other stuff going on ... - * // - * // asynchronous completion including api (client) - * .perform(function(client, done) { - * console.log('elementValue', elementValue); - * // similar to before, but now with client - * // potentially other async stuff going on - * // on finished, call the done callback - * done(); - * }); - * }; - * ``` - * - * @param callback: The function to run as part of the queue. Its signature can have up to two parameters. No parameters: callback runs and - * perform completes immediately at the end of the execution of the callback. One parameter: allows for asynchronous execution within the - * callback providing a done callback function for completion as the first argument. Two parameters: allows for asynchronous execution - * with the "api" object passed in as the first argument, followed by the done callback. - */ - perform(callback: (browser: this, done?: () => void) => void): this; - - /** - * A simple perform command which allows access to the "api" in a callback. Can be useful if you want to read variables set by other commands. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * var elementValue; - * browser - * .getValue('.some-element', function(result) { - * elementValue = result.value; - * }) - * // other stuff going on ... - * // - * // asynchronous completion - * .perform(function(done) { - * console.log('elementValue', elementValue); - * // potentially other async stuff going on - * // on finished, call the done callback - * done(); - * }) - * }; - * ``` - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * var elementValue; - * browser - * .getValue('.some-element', function(result) { - * elementValue = result.value; - * }) - * // other stuff going on ... - * // - * // self-completing callback - * .perform(function() { - * console.log('elementValue', elementValue); - * // without any defined parameters, perform - * // completes immediately (synchronously) - * }) - * // - * }; - * ``` - * @param callback: The function to run as part of the queue. Its signature can have up to two parameters. No parameters: callback runs and - * perform completes immediately at the end of the execution of the callback. One parameter: allows for asynchronous execution within the - * callback providing a done callback function for completion as the first argument. Two parameters: allows for asynchronous execution - * with the "api" object passed in as the first argument, followed by the done callback. - */ - perform(callback: (done?: () => void) => void): this; // tslint:disable-line:unified-signatures - - /** - * Resizes the current window. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.resizeWindow(1000, 800); - * }; - * ``` - * @param width: The new window width. - * @param height: The new window height. - * @param callback: Optional callback function to be called when the command finishes. - */ - resizeWindow(width: number, height: number, callback?: () => void): this; - - /** - * Take a screenshot of the current page and saves it as the given filename. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.saveScreenshot('/path/to/fileName.png'); - * }; - * ``` - * @param fileName: The complete path to the file name where the screenshot should be saved. - * @param callback: Optional callback function to be called when the command finishes. - */ - saveScreenshot(fileName: string, callback?: () => void): this; + page: { + [name: string]: () => EnhancedPageObject; + } & NightwatchCustomPageObjects; /** * SessionId of the session used by the Nightwatch api. @@ -1122,691 +908,55 @@ export interface NightwatchAPI extends SharedFunctions { /** * Override the sessionId used by Nightwatch client with another session id. - * @param sessionId: The session Id to set. */ setSessionId(sessionId: string): this; - /** - * Set a cookie, specified as a cookie JSON object, as defined https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object. - * Uses cookie protocol command. - * - * Usage: - * ``` - * this.demoTest = function(browser) { - * browser.setCookie({ - * name : "test_cookie", - * value : "test_value", - * path : "/", (Optional) - * domain : "example.org", (Optional) - * secure : false, (Optional) - * httpOnly : false, // (Optional) - * expiry : 1395002765 // (Optional) time in seconds since midnight, January 1, 1970 UTC - * }); - * } - * ``` - * @param cookie: The cookie object. - * @param callback: Optional callback function to be called when the command finishes. - */ - setCookie(cookie: any, callback?: () => void): this; - - /** - * Sets the current window position. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.setWindowPosition(0, 0); - * }; - * ``` - * @param OffsetX: The new window offset x-position. - * @param OffsetY: The new window offset y-position. - * @param callback: ptional callback function to be called when the command finishes. - */ - setWindowPosition(OffsetX: number, OffsetY: number, callback?: () => void): this; - - /** - * Change focus to another window. The window to change focus to may be specified by its server assigned window handle, or by the value of its name attribute. - * To find out the window handle use window_handles protocol action - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.window_handles(function(result) { - * var handle = result.value[0]; - * browser.switchWindow(handle); - * }); - * }; - * ``` - * @param handleOrName: The server assigned window handle or the name attribute. - * @param callback: Optional callback function to be called when the command finishes. - */ - switchWindow(handleOrName: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Convenience method that adds the specified hash (i.e. url fragment) to the current value of the launch_url as set in nightwatch.json. - * - * Usage: - * ``` - * this.demoTest = function (client) { - * client.urlHash('#hashvalue'); - * // or - * client.urlHash('hashvalue'); - * }; - * ``` - * @param hash: The hash to add/replace to the current url (i.e. the value set in the launch_url property in nightwatch.json). - * @param callback: - */ - urlHash(hash: string): this; - - /** - * Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog. - * @param callback: Optional callback function to be called when the command finishes. - */ - acceptAlert(callback?: () => void): this; - - /** - * Navigate backwards in the browser history, if possible. - * @param callback: Optional callback function to be called when the command finishes. - */ - back(callback?: () => void): this; - - /** - * Get a list of the available contexts. - * Used by Appium when testing hybrid mobile web apps. More info here: https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/hybrid.md. - * @param callback: Callback function to be called when the command finishes. - * @returns an array of strings representing available contexts, e.g 'WEBVIEW', or 'NATIVE' - */ - contexts(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Retrieve or delete all cookies visible to the current page or set a cookie. - * @returns a string representing the current context or `null`, representing "no context" - */ - cookie(method: string, callbackorCookie?: () => void): this; - - /** - * Get current context. - * @param callback: Callback function to be called when the command finishes. - */ - currentContext(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Dismisses the currently displayed alert dialog. For confirm() and prompt() dialogs, this is equivalent to clicking the 'Cancel' button. - * For alert() dialogs, this is equivalent to clicking the 'OK' button. - * @param callback: Optional callback function to be called when the command finishes. - */ - dismissAlert(callback?: () => void): this; - - /** - * Double-clicks at the current mouse coordinates (set by moveto). - * @param callback: Optional callback function to be called when the command finishes. - */ - doubleClick(callback?: () => void): this; - - /** - * Search for an element on the page, starting from the document root. The located element will be returned as a WebElement JSON object. - * - * Usage: - * ``` - * module.exports = { - * 'demo Test' : function(browser) { - * browser.element('css selector', 'body', function(res) { - * console.log(res) - * }); - * } - * }; - * ``` - * @param using: The locator's strategy to use. - * @param value: The search target. - * @param callback: Optional callback function to be called when the command finishes. - */ - element(using: string, value: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Get the element on the page that currently has focus. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementActive(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Get the value of an element's attribute. - * @param id: ID of the element to route the command to. - * @param attributeName: The attribute name - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdAttribute(id: string, attributeName: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Clear a TEXTAREA or text INPUT element's value. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdClear(id: string, callback?: () => void): this; - - /** - * Click on an element. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdClick(id: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Query the value of an element's computed CSS property. - * The CSS property to query should be specified using the CSS property name, not the JavaScript property name (e.g. background-color instead of backgroundColor). - */ - elementIdCssProperty(id: string, cssPropertyName: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Determine if an element is currently displayed. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdDisplayed(id: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Search for an element on the page, starting from the identified element. The located element will be returned as a WebElement JSON object. - * @param id: ID of the element to route the command to. - * @param using: The locator strategy to use. - * @param value: The search target. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdElement(id: string, using: string, value: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Search for multiple elements on the page, starting from the identified element. The located element will be returned as a WebElement JSON objects. - * @param id: ID of the element to route the command to. - * @param using: The locator strategy to use. - * @param value: The search target. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdElements(id: string, using: string, value: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Determine if an element is currently enabled. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdEnabled(id: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Test if two element IDs refer to the same DOM element. - * @param id: ID of the element to route the command to. - * @param otherId: ID of the element to compare against. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdEquals(id: string, otherId: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page. - * The element's coordinates are returned as a JSON object with x and y properties. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The X and Y coordinates for the element on the page. - */ - elementIdLocation(id: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Determine an element's location on the screen once it has been scrolled into view. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdLocationInView(id: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Query for an element's tag name. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdName(id: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Determine if an OPTION element, or an INPUT element of type checkbox or radio button is currently selected. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdSelected(id: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Determine an element's size in pixels. The size will be returned as a JSON object with width and height properties. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdSize(id: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Returns the visible text for the element. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - elementIdText(id: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Send a sequence of key strokes to an element or returns the current value of the element. - * @param id: ID of the element to route the command to. - * @param value: Value to send to element in case of POST - */ - elementIdValue(id: string, value?: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Search for multiple elements on the page, starting from the document root. The located elements will be returned as a WebElement JSON objects. - * Valid strings to use as locator strategies are: "class name", "css selector", "id", "name", "link text", "partial link text", "tag name", "xpath" - * @param using: The locator strategy to use. - * @param value: The search target. - * @param callback: Callback function to be invoked with the result when the command finishes. - */ - elements(using: string, value: string, callback: (result: NightwatchCallbackResult) => void): this; - - /** - * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous and - * the result of evaluating the script is returned to the client. - * The script argument defines the script to execute in the form of a function body. The value returned by that function will be returned to the client. - * The function will be invoked with the provided args array and the values may be accessed via the arguments object in the order specified. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.execute(function(data) { - * // resize operation - * return true; - * }, [imagedata], function(result) { - * ... - * }); - * }; - * ``` - * @param body: The function body to be injected. - * @param args: An array of arguments which will be passed to the function. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The script result. - */ - execute(body: ((...data: any[]) => void) | string, args?: any[], callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be asynchronous - * and the result of evaluating the script is returned to the client. - * Asynchronous script commands may not span page loads. If an unload event is fired while waiting for a script result, an error should be returned to the client. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.executeAsync(function(data, done) { - * someAsyncOperation(function() { - * done(true); - * }); - * }, [imagedata], function(result) { - * // ... - * }); - * }; - * ``` - * @param script: The function body to be injected. - * @param args: An array of arguments which will be passed to the function. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The script result. - */ - executeAsync(script: ((...data: any[]) => void) | string, args?: any[], callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Navigate forwards in the browser history, if possible. - * @param callback: Optional callback function to be called when the command finishes. - */ - forward(callback?: () => void): this; - - /** - * Change focus to another frame on the page. If the frame id is missing or null, the server should switch to the page's default content. - * @param frameId: Identifier for the frame to change focus to. - * @param callback: Optional callback function to be called when the command finishes. - */ - frame(frameId: string | undefined | null, callback?: () => void): this; - - /** - * Change focus to the parent context. If the current context is the top level browsing context, the context remains unchanged. - * @param callback: Optional callback function to be called when the command finishes. - */ - frameParent(callback?: () => void): this; - - /** - * Gets the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The text of the currently displayed alert. - */ - getAlertText(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Get the current browser orientation. - * @param callback: Callback function to be called when the command finishes. - * @returns The current browser orientation: LANDSCAPE|PORTRAIT - */ - getOrientation(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Send a sequence of key strokes to the active element. The sequence is defined in the same format as the sendKeys command. - * An object map with available keys and their respective UTF-8 characters, as defined on W3C WebDriver draft spec, is loaded onto the main Nightwatch instance as client.Keys. - * Rather than the setValue, the modifiers are not released at the end of the call. - * The state of the modifier keys is kept between calls, so mouse interactions can be performed while modifier keys are depressed. - * @param keysToSend: The keys sequence to be sent. - * @param callback: Optional callback function to be called when the command finishes. - */ - keys(keysToSend: string[], callback?: () => void): this; - - /** - * Click at the current mouse coordinates (set by moveto). - * The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button, and if you don't pass in a button but do pass in a callback, it will handle it correctly. - * @param button: The mouse button - * @param callback: Optional callback function to be called when the command finishes. - */ - mouseButtonClick(button: string, callback?: () => void): this; - - /** - * Click and hold the left mouse button (at the coordinates set by the last moveto command). Note that the next mouse-related command that should follow is mouseButtonUp . - * Any other mouse command (such as click or another call to buttondown) will yield undefined behaviour. - * Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). - * It defaults to left mouse button, and if you don't pass in a button but do pass in a callback, it will handle it correctly. - * @param button: The mouse button - * @param callback: Optional callback function to be called when the command finishes. - */ - mouseButtonDown(button: string, callback?: () => void): this; - - /** - * Releases the mouse button previously held (where the mouse is currently at). Must be called once for every mouseButtonDown command issued. - * Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). - * It defaults to left mouse button, and if you don't pass in a button but do pass in a callback, it will handle it correctly. - * @param button: The mouse button - * @param callback: Optional callback function to be called when the command finishes. - */ - mouseButtonUp(button: string, callback?: () => void): this; - - /** - * Move the mouse by an offset of the specificed element. If no element is specified, the move is relative to the current mouse cursor. - * If an element is provided but no offset, the mouse will be moved to the center of the element. - * If the element is not visible, it will be scrolled into view. - * @param element: Opaque ID assigned to the element to move to. If not specified or is null, the offset is relative to current position of the mouse. - * @param xofset: X offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element. - * @param yoffset: Y offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element. - * @param callback: Optional callback function to be called when the command finishes. - */ - moveTo(element: string, xofset: number, yoffset: number, callback?: () => void): this; - - /** - * Refresh the current page. - * @param callback: Optional callback function to be called when the command finishes. - */ - refresh(callback?: () => void): this; - - /** - * Take a screenshot of the current page. - * @param log_screenshot_data: Whether or not the screenshot data should appear in the logs when running with --verbose - * @param callback: Optional callback function to be called with the resultant value (Base64 PNG) when the command finishes. - */ - screenshot(log_screenshot_data: boolean, callback?: (screenshotEncoded: string) => void): this; - - /** - * Get info about, delete or create a new session. Defaults to the current session. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.session(function(result) { - * console.log(result.value); - * }); - * // - * browser.session('delete', function(result) { - * console.log(result.value); - * }); - * // - * browser.session('delete', '12345-abc', function(result) { - * console.log(result.value); - * }); - * }; - * ``` - * @param action: The http verb to use, can be "get", "post" or "delete". If only the callback is passed, get is assumed as default. - * @param sessionId: The id of the session to get info about or delete. - * @param callback: Optional callback function to be called when the command finishes. - */ - session(action?: string, sessionId?: string, callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Gets the text of the log type specified - * @param typeString: Type of log to request - * @param callback: Optional callback function to be called when the command finishes. - * @returns Array of the text entries of the log. - */ - sessionLog(typeString: string, callback?: (log: NightwatchLogEntry[]) => void): this; - - /** - * Gets an array of strings for which log types are available. - * @param callback: Optional callback function to be called when the command finishes. - * @returns Available log types - */ - sessionLogTypes(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Returns a list of the currently active sessions. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser.sessions(function(result) { - * console.log(result.value); - * }); - * }; - * ``` - * @param callback: Optional callback function to be called when the command finishes. - */ - sessions(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Sends keystrokes to a JavaScript prompt() dialog. - * @param value: Keystrokes to send to the prompt() dialog - * @param callback: Optional callback function to be called when the command finishes. - */ - setAlertText(value: string, callback?: () => void): this; - - /** - * Sets the context - * @param context: context name to switch to - a string representing an available context. - * @param callback: Optional callback function to be called when the command finishes. - */ - setContext(context: string, callback?: () => void): this; - - /** - * Sets the browser orientation. - * @param orientation: The new browser orientation: {LANDSCAPE|PORTRAIT} - * @param callback: Optional callback function to be called when the command finishes. - */ - setOrientation(orientation: string, callback?: () => void): this; - - /** - * Get the current page source. - * @param callback: Optional callback function to be called when the command finishes. - */ - source(callback?: () => void): this; - - /** - * Query the server's current status. - * @param callback: Optional callback function to be called when the command finishes. - */ - status(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element. - * @param id: ID of the element to route the command to. - * @param callback: Optional callback function to be called when the command finishes. - */ - submit(id: string, callback?: () => void): this; - - /** - * Configure the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client. - * @param typeOfOperation: The type of operation to set the timeout for. - * Valid values are: "script" for script timeouts, "implicit" for modifying the implicit wait timeout and "page load" for setting a page load timeout. - * @param ms: The amount of time, in milliseconds, that time-limited commands are permitted to run. - * @param callback: Optional callback function to be called when the command finishes. - */ - timeouts(typeOfOperation: string, ms: number, callback?: () => void): this; - - /** - * Set the amount of time, in milliseconds, that asynchronous scripts executed by /session/:sessionId/execute_async are permitted - * to run before they are aborted and a |Timeout| error is returned to the client. - * @param ms: The amount of time, in milliseconds, that time-limited commands are permitted to run. - * @param callback: Optional callback function to be called when the command finishes. - */ - timeoutsAsyncScript(ms: number, callback?: () => void): this; - - /** - * Set the amount of time the driver should wait when searching for elements. If this command is never sent, the driver will default to an implicit wait of 0ms. - * @param ms: The amount of time, in milliseconds, that time-limited commands are permitted to run. - * @param callback: Optional callback function to be called when the command finishes. - */ - timeoutsImplicitWait(ms: number, callback?: () => void): this; - - /** - * Get the current page title. - * @param expected: The expected page title. - * @param msg: Optional log message to display in the output. If missing, one is displayed by default. - * @param callback: Optional callback function to be called when the command finishes. - */ - title(expected: string, msg?: string, callback?: () => void): this; - - /** - * Retrieve the URL of the current page or navigate to a new URL. - * - * Usage: - * ``` - * module.exports = { - * 'demo Test' : function(browser) { - * browser.url(function(result) { - * // return the current url - * console.log(result); - * }); - * // - * // navigate to new url: - * browser.url('{URL}'); - * // - * // - * // navigate to new url: - * browser.url('{URL}', function(result) { - * console.log(result); - * }); - * } - * }; - * ``` - * @param url: If missing, it will return the URL of the current page as an argument to the supplied callback - * @param callback Optional callback function to be called when the command finishes. - */ - url(url?: string | ((result: NightwatchCallbackResult) => void), callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Change focus to another window or close the current window. - * @param method: The HTTP method to use - * @param handleOrName: The window to change focus to. - * @param callback: Optional callback function to be called when the command finishes. - */ - window(method: string, handleOrName: string, callback?: () => void): this; - - /** - * Retrieve the current window handle. - * @param callback: Optional callback function to be called when the command finishes. - */ - windowHandle(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Retrieve the list of all window handles available to the session. - * @param callback: Optional callback function to be called when the command finishes. - */ - windowHandles(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Retrieve the list of all window handles available to the session. - * @param callback: Optional callback function to be called when the command finishes. - */ - window_handles(callback?: (result: NightwatchCallbackResult) => void): this; - - /** - * Retrieve the current window handle. - * @param handleOrName: windowHandle URL parameter; if it is "current", the currently active window will be maximized. - * @param callback: Optional callback function to be called when the command finishes. - */ - windowMaximize(handleOrName?: string, callback?: () => void): this; - - /** - * Change or get the position of the specified window. If the second argument is a function it will be used as a callback and the call - * will perform a get request to retrieve the existing window position. - * @param windowHandle: - * @param: offsetX: - * @param: offsetY: - * @param: callback: - */ - windowPosition(windowHandle: string, offsetX: number, offsetY: number, callback: (result: NightwatchCallbackResult) => void): this; - - /** - * Change or get the size of the specified window. If the second argument is a function it will be used as a callback and the call will perform a get request to retrieve the existing window size. - * @param windowHandle: - * @param width: - * @param height: - * @param callback: Optional callback function to be called when the command finishes. - */ - windowSize(windowHandle: string, width: number, height: number, callback?: () => void): this; - - /** - * To switch to xpath selectors instead of css as the locate strategy. - * To always use xpath by default set the property "use_xpath": true in your test settings. - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser - * .useXpath() // every selector now must be xpath - * .click("//tr[@data-recordid]/span[text()='Search Text']"); - * }; - * ``` - */ - useXpath(): this; - - /** - * To switch to css selectors instead of xpath as the locate strategy - * - * Usage: - * ``` - * this.demoTest = function (browser) { - * browser - * .useCss() // we're back to CSS now - * .setValue('input[type=text]', 'nightwatch'); - * }; - * ``` - */ - useCss(): this; - options: NightwatchTestOptions; Keys: NightwatchKeys; currentTest: NightwatchTestSuite; - globals: any; + globals: NightwatchGlobals; + launchUrl: string; launch_url: string; } -/* tslint:disable-next-line:no-empty-interface */ -export interface NightwatchCustomCommands {} +// tslint:disable-next-line +export interface NightwatchCustomCommands { } -/* tslint:disable-next-line:no-empty-interface */ -export interface NightwatchCustomAssertions {} +// tslint:disable-next-line +export interface NightwatchCustomAssertions { } -export interface NightwatchBrowser extends NightwatchAPI, NightwatchCustomCommands, NightwatchCustomAssertions, NightwatchCustomPageObjects { } +// tslint:disable-next-line +export interface NightwatchCustomPageObjects { } + +export interface NightwatchBrowser extends NightwatchAPI, NightwatchCustomCommands { +} export type NightwatchTest = (browser: NightwatchBrowser) => void; export interface NightwatchTestFunctions { - [key: string]: NightwatchTest; -} - -export type NightwatchTestHook = (browser: NightwatchBrowser, done: () => void) => void; - -export interface NightwatchTestHooks { before?: NightwatchTestHook; after?: NightwatchTestHook; beforeEach?: NightwatchTestHook; afterEach?: NightwatchTestHook; - '@disabled'?: boolean; + "@tags"?: string | string[]; + "@disabled"?: boolean; + [key: string]: any; +} + +export type NightwatchTestHook = + | ((browser: NightwatchBrowser, done: (err?: any) => void) => void) + | ((done: (err?: any) => void) => void) + ; + +export interface NightwatchTestHooks extends NightwatchGlobals { + before?: NightwatchTestHook; + after?: NightwatchTestHook; + beforeEach?: NightwatchTestHook; + afterEach?: NightwatchTestHook; } export type NightwatchTests = NightwatchTestFunctions | NightwatchTestHooks; @@ -1822,21 +972,21 @@ export type NightwatchAssert = (passed: boolean, receivedValue?: any, expectedVa * * All assertions must implement the following api: * - * - @param {boolean|function} expected + * - @param {T|function} expected * - @param {string} message * - @param {function} pass * - @param {function} value * - @param {function} command * - @param {function} - Optional failure */ -export interface NightwatchAssertion { - expected: (() => void) | boolean; +export interface NightwatchAssertion { + expected: (() => T) | T; message: string; - pass(...args: any[]): any; - value(...args: any[]): any; - command(...args: any[]): any; - failure?(...args: any[]): any; - api?: NightwatchAPI; + pass(value: T): any; + value(result: U): T; + command(callback: (result: U) => void): this; + failure?(result: U): boolean; + api: NightwatchAPI; } export interface NightwatchClient { @@ -1847,8 +997,14 @@ export interface NightwatchClient { export interface Nightwatch { api: NightwatchAPI; client: NightwatchClient; + + assert: NightwatchAssertions; + expect: Expect; + verify: NightwatchAssertions; } +export type LocateStrategy = "class name" | "css selector" | "id" | "name" | "link text" | "partial link text" | "tag name" | "xpath"; + /** * #### [Enhanced Element Instances](https://github.com/nightwatchjs/nightwatch/wiki/Page-Object-API#enhanced-element-instances) * Element instances encapsulate the definition used to handle element selectors. @@ -1856,7 +1012,7 @@ export interface Nightwatch { * instead referring to them using their `@`-prefixed names for selector arguments, * but they are available through a page object or section's elements property. */ -export interface EnhancedElementInstance { +export interface EnhancedElementInstance { /** * The name of the element as defined by its key in the parent section or the page object's `elements` definition. * This is the same name used with the `@` prefix in selector arguments for page object commands that refer to the element. @@ -1866,13 +1022,13 @@ export interface EnhancedElementInstance { /** * The locate strategy to be used with `selector` when finding the element within the DOM. */ - locateStrategy: string; + locateStrategy: LocateStrategy; /** * A reference to the parent object instance. * This is the parent section or the page object that contained the definition for this object. */ - parent: EnhancedPageObject; + parent: T; /** * The selector string used to find the element in the DOM. @@ -1880,6 +1036,12 @@ export interface EnhancedElementInstance { selector: string; } +export type EnhancedSectionInstance = EnhancedPageObject; + +export interface EnhancedPageObjectSections { + [name: string]: EnhancedSectionInstance; +} + /** * #### [Enhanced Page Object Instances](https://github.com/nightwatchjs/nightwatch/wiki/Page-Object-API#enhanced-page-object-instances) * Page object module definitions are used to define page object instances when their respective factory functions within the page reference of the standard command API is called. @@ -1888,392 +1050,1483 @@ export interface EnhancedElementInstance { * ``` * Every time a factory function like MyPage above is called, a new instance of the page object is instantiated. */ -export interface EnhancedPageObject extends SharedFunctions { - /** - * A reference providing access to the full Nightwatch command API, - * usually known as "client" or "browser" in test cases. - * This is used to access those commands that are not part of the subset of commands within the page object API. - */ - api: NightwatchAPI; - +export type EnhancedPageObject = Nightwatch & SharedCommands & NightwatchCustomCommands & Commands & { /** * A map of Element objects (see [Enhanced Element Instances](https://github.com/nightwatchjs/nightwatch/wiki/Page-Object-API#enhanced-element-instances)) used by element selectors. */ - elements: {[name: string]: EnhancedElementInstance}; + elements: { + [name: string]: EnhancedElementInstance>; + }; + + section: Sections; /** * The name of the page object as defined by its module name (not including the extension). * This is the same name used to access the `page` object factory from the page reference in the command API. */ name: string; + + /** + * This command is an alias to url and also a convenience method because when called without any arguments + * it performs a call to .url() with passing the value of `url` property on the page object. + * Uses `url` protocol command. + */ + navigate(url?: string, callback?: () => void): EnhancedPageObject; +}; + +export interface Cookie { + name: string; + value: string; + path: string; + domain: string; + secure: boolean; } -export interface SharedFunctions { +export interface SharedCommands extends ClientCommands, ElementCommands { } + +export interface ClientCommands { /** - * Clear a textarea or a text input element's value. Uses elementIdValue protocol command. + * Close the current window. This can be useful when you're working with multiple windows open (e.g. an OAuth login). + * Uses `window` protocol command. * - * Usage: - * ``` + * @example * this.demoTest = function (client) { - * client.clearValue('input[type=text]'); + * client.closeWindow(); * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. + * + * @see window */ - clearValue(selector: string, callback?: () => void): this; + closeWindow(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; /** - * Simulates a click event on the given DOM element. Uses elementIdClick protocol command. + * Delete the cookie with the given name. This command is a no-op if there is no such cookie visible to the current page. * - * Usage: - * ``` - * this.demoTest = function (client) { - * client.click("#main ul li a.first"); - * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. + * @example + * this.demoTest = function(browser) { + * browser.deleteCookie("test_cookie", function() { + * // do something more in here + * }); + * } + * + * @see cookie */ - click(selector: string, callback?: () => void): this; + deleteCookie(cookieName: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; /** - * Retrieve the value of an attribute for a given DOM element. Uses elementIdAttribute protocol command. + * Delete all cookies visible to the current page. * - * Usage: - * ``` + * @example + * this.demoTest = function(browser) { + * browser.deleteCookies(function() { + * // do something more in here + * }); + * } + * + * @see cookie + */ + deleteCookies(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Ends the session. Uses session protocol command. + * + * @example + * this.demoTest = function (browser) { + * browser.end(); + * }; + * + * @see session + */ + end(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Retrieve a single cookie visible to the current page. The cookie is returned as a cookie JSON object, + * as defined [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object). + * + * Uses `cookie` protocol command. + * + * @example + * this.demoTest = function(browser) { + * browser.getCookie(name, function callback(result) { + * this.assert.equal(result.value, '123456'); + * this.assert.equals(result.name, 'test_cookie'); + * }); + * } + * + * @see cookie + */ + getCookie(name: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Retrieve all cookies visible to the current page. The cookies are returned as an array of cookie JSON object, + * as defined [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object). + * + * Uses `cookie` protocol command. + * + * @example + * this.demoTest = function(browser) { + * browser.getCookies(function callback(result) { + * this.assert.equal(result.value.length, 1); + * this.assert.equals(result.value[0].name, 'test_cookie'); + * }); + * } + * + * @see cookie + */ + getCookies(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Gets a log from Selenium. + * + * @example + * this.demoTest = function(client) { + * this.getLog('browser', function(logEntriesArray) { + * console.log('Log length: ' + logEntriesArray.length); + * logEntriesArray.forEach(function(log) { + * console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message); + * }); + * }); + * }; + * + * @see getLogTypes + */ + getLog(typestring: string, callback?: (this: NightwatchAPI, log: NightwatchLogEntry[]) => void): this; + + /** + * Gets the available log types. More info about log types in WebDriver can be found here: https://github.com/SeleniumHQ/selenium/wiki/Logging + * + * @example + * this.demoTest = function(client) { + * this.getLogTypes(function(typesArray) { + * console.log(typesArray); + * }); + * }; + * + * @see sessionLogTypes + */ + getLogTypes(callback?: (this: NightwatchAPI, result: Array<"client" | "driver" | "browser" | "server">) => void): this; + + /** + * Returns the title of the current page. Uses title protocol command. + * + * @example + * this.demoTest = function (browser) { + * browser.getTitle(function(title) { + * this.assert.equal(typeof title, 'string'); + * this.assert.equal(title, 'Nightwatch.js'); + * }); + * }; + * + * @see title + */ + getTitle(callback?: (this: NightwatchAPI, result?: string) => void): this; + + /** + * This command is an alias to url and also a convenience method when called without any arguments in the sense + * that it performs a call to .url() with passing the value of `launch_url` field from the settings file. + * Uses `url` protocol command. + * + * @example * this.demoTest = function (client) { - * client.getAttribute("#main ul li a.first", "href", function(result) { - * this.assert.equal(typeof result, "object"); - * this.assert.equal(result.status, 0); - * this.assert.equal(result.value, "#home"); + * client.init(); + * }; + * + * @see url + */ + init(url?: string): this; + + /** + * Utility command to load an external script into the page specified by url. + * + * @example + * this.demoTest = function(client) { + * this.injectScript("{script-url}", function() { + * // we're all done here. + * }); + * }; + */ + injectScript(scriptUrl: string, id?: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Utility command to test if the log type is available. + * + * @example + * this.demoTest = function(browser) { + * browser.isLogAvailable('browser', function(isAvailable) { + * // do something more in here + * }); + * } + * + * @see getLogTypes + */ + isLogAvailable(typeString: string, callback?: (this: NightwatchAPI, result: boolean) => void): this; + + /** + * Maximizes the current window. + * + * @example + * this.demoTest = function (browser) { + * browser.maximizeWindow(); + * }; + * + * @see windowMaximize + */ + maximizeWindow(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Suspends the test for the given time in milliseconds. If the milliseconds argument is missing it will suspend the test indefinitely + * + * @example + * this.demoTest = function (browser) { + * browser.pause(1000); + * // or suspend indefinitely + * browser.pause(); + * }; + */ + pause(ms?: number, callback?: (this: NightwatchAPI) => void): this; + + /** + * A simple perform command which allows access to the Nightwatch API in a callback. Can be useful if you want to read variables set by other commands. + * + * The callback signature can have up to two parameters. + * - no parameters: callback runs and perform completes immediately at the end of the execution of the callback. + * - one parameter: allows for asynchronous execution within the callback providing a done callback function for completion as the first argument. + * - two parameters: allows for asynchronous execution with the Nightwatch `api` object passed in as the first argument, followed by the done callback. + * + * @example + * this.demoTest = function (browser) { + * var elementValue; + * browser + * .getValue('.some-element', function(result) { + * elementValue = result.value; + * }) + * // other stuff going on ... + * // + * // self-completing callback + * .perform(function() { + * console.log('elementValue', elementValue); + * // without any defined parameters, perform + * // completes immediately (synchronously) + * }) + * // + * // asynchronous completion + * .perform(function(done) { + * console.log('elementValue', elementValue); + * // potentially other async stuff going on + * // on finished, call the done callback + * done(); + * }) + * // + * // asynchronous completion including api (client) + * .perform(function(client, done) { + * console.log('elementValue', elementValue); + * // similar to before, but now with client + * // potentially other async stuff going on + * // on finished, call the done callback + * done(); + * }); + * }; + */ + perform( + callback: + | (() => (undefined | Promise)) + | ((done: () => void) => void) + | ((client: NightwatchAPI, done: () => void) => void) + ): this; + + /** + * Resizes the current window. + * + * @example + * this.demoTest = function (browser) { + * browser.resizeWindow(1000, 800); + * }; + * + * @see windowSize + */ + resizeWindow(width: number, height: number, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Take a screenshot of the current page and saves it as the given filename. + * + * @example + * this.demoTest = function (browser) { + * browser.saveScreenshot('/path/to/fileName.png'); + * }; + * + * @see screenshot + */ + saveScreenshot(fileName: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Set a cookie, specified as a cookie JSON object, as defined [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object). + * + * Uses `cookie` protocol command. + * + * @example + * this.demoTest = function(browser) { + * browser.setCookie({ + * name : "test_cookie", + * value : "test_value", + * path : "/", (Optional) + * domain : "example.org", (Optional) + * secure : false, (Optional) + * httpOnly : false, // (Optional) + * expiry : 1395002765 // (Optional) time in seconds since midnight, January 1, 1970 UTC + * }); + * } + * + * @see cookie + */ + setCookie(cookie: Cookie, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Sets the current window position. + * + * @example + * this.demoTest = function (browser) { + * browser.setWindowPosition(0, 0); + * }; + * + * @see windowPosition + */ + setWindowPosition(offsetX: number, offsetY: number, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Change focus to another window. The window to change focus to may be specified by its server assigned window handle, or by the value of its name attribute. + * + * To find out the window handle use `windowHandles` command + * + * @example + * this.demoTest = function (browser) { + * browser.windowHandles(function(result) { + * var handle = result.value[0]; + * browser.switchWindow(handle); + * }); + * }; + * + * this.demoTestAsync = async function (browser) { + * const result = browser.windowHandles(); + * var handle = result.value[0]; + * browser.switchWindow(handle); + * }; + * + * @see window + */ + switchWindow(handleOrName: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Convenience command that adds the specified hash (i.e. url fragment) to the current value of the `launch_url` as set in `nightwatch.json`. + * + * @example + * this.demoTest = function (client) { + * client.urlHash('#hashvalue'); + * // or + * client.urlHash('hashvalue'); + * }; + * + * @see url + */ + urlHash(hash: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Sets the locate strategy for selectors to `css selector`, therefore every following selector needs to be specified as css. + * + * @example + * this.demoTest = function (browser) { + * browser + * .useCss() // we're back to CSS now + * .setValue('input[type=text]', 'nightwatch'); + * }; + */ + useCss(callback?: (this: NightwatchAPI) => void): this; + + /** + * Sets the locate strategy for selectors to xpath, therefore every following selector needs to be specified as xpath. + * + * @example + * this.demoTest = function (browser) { + * browser + * .useXpath() // every selector now must be xpath + * .click("//tr[@data-recordid]/span[text()='Search Text']"); + * }; + */ + useXpath(callback?: (this: NightwatchAPI) => void): this; +} + +export interface ElementCommands { + /** + * Clear a textarea or a text input element's value. Uses `elementIdValue` protocol action internally. + * + * @example + * this.demoTest = function (browser) { + * browser.clearValue('input[type=text]'); + * }; + * + * @see elementIdClear + */ + clearValue(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Simulates a click event on the given DOM element. Uses `elementIdClick` protocol action internally. + * + * The element is scrolled into view if it is not already pointer-interactable. + * See the WebDriver specification for element interactability + * + * @example + * this.demoTest = function (browser) { + * browser.click("#main ul li a.first"); + * }; + * + * @see elementIdClick + */ + click(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Retrieve the value of an attribute for a given DOM element. Uses `elementIdAttribute` protocol command. + * + * @example + * this.demoTest = function (browser) { + * browser.getAttribute("#main ul li a.first", "href", function(result) { + * this.assert.equal(typeof result, "object"); + * this.assert.equal(result.status, 0); + * this.assert.equal(result.value, "#home"); + * }); + * }; + * + * @see elementIdAttribute + */ + getAttribute(selector: string, attribute: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Retrieve the value of a css property for a given DOM element. Uses `elementIdCssProperty` protocol command. + * + * @example + * this.demoTest = function (browser) { + * browser.getCssProperty("#main ul li a.first", "display", function(result) { + * this.assert.equal(typeof result, "object"); + * this.assert.equal(result.status, 0); + * this.assert.equal(result.value, 'inline'); + * }); + * }; + * + * @see elementIdCssProperty + */ + getCssProperty(selector: string, cssProperty: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Determine an element's size in pixels. Uses `elementIdSize` protocol command. + * + * @example + * this.demoTest = function (browser) { + * browser.getElementSize("#main ul li a.first", function(result) { + * this.assert.equal(typeof result, "object"); + * this.assert.equal(result.status, 0); + * this.assert.equal(result.value.width, 500); + * this.assert.equal(result.value.height, 20); * }); * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param attribute: The attribute name to inspect. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The value of the attribute - */ - getAttribute(selector: string, attribute: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; - - /** - * Retrieve the value of a css property for a given DOM element. Uses elementIdCssProperty protocol command. * - * Usage: - * ``` - * this.demoTest = function (client) { - * client.getCssProperty("#main ul li a.first", "display", function(result) { - * this.assert.equal(typeof result, "object"); - * this.assert.equal(result.status, 0); - * this.assert.equal(result.value, 'inline'); - * }); - * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param cssProperty: The CSS property to inspect. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The value of the css property + * @see elementIdSize */ - getCssProperty(selector: string, cssProperty: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; - - /** - * Determine an element's size in pixels. Uses elementIdSize protocol command. - * - * Usage: - * ``` - * this.demoTest = function (client) { - * client.getElementSize("#main ul li a.first", function(result) { - * this.assert.equal(typeof result, "object"); - * this.assert.equal(result.status, 0); - * this.assert.equal(result.value.width, 500); - * this.assert.equal(result.value.height, 20); - * }); - * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The width and height of the element in pixels - */ - getElementSize(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + getElementSize(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ width: number; height: number }>) => void): this; /** * Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page. - * The element's coordinates are returned as a JSON object with x and y properties. Uses elementIdLocation protocol command. * - * Usage: - * ``` - * this.demoTest = function (client) { - * client.getLocation("#main ul li a.first", function(result) { - * this.assert.equal(typeof result, "object"); - * this.assert.equal(result.status, 0); - * this.assert.equal(result.value.x, 200); - * this.assert.equal(result.value.y, 200); - * }); - * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The X and Y coordinates for the element on the page - */ - getLocation(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; - - /** - * Determine an element's location on the screen once it has been scrolled into view. Uses elementIdLocationInView protocol command. + * The element's coordinates are returned as a JSON object with x and y properties. Uses `elementIdLocation` protocol command. * - * Usage: - * ``` + * @example * this.demoTest = function (browser) { - * browser.getLocationInView("#main ul li a.first", function(result) { - * this.assert.equal(typeof result, "object"); - * this.assert.equal(result.status, 0); - * this.assert.equal(result.value.x, 200); - * this.assert.equal(result.value.y, 200); - * }); + * browser.getLocation("#main ul li a.first", function(result) { + * this.assert.equal(typeof result, "object"); + * this.assert.equal(result.status, 0); + * this.assert.equal(result.value.x, 200); + * this.assert.equal(result.value.y, 200); + * }); * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The X and Y coordinates for the element on the page. + * + * @see elementIdLocation */ - getLocationInView(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + getLocation(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ x: number; y: number }>) => void): this; /** - * Query for an element's tag name. Uses elementIdName protocol command. + * Determine an element's location on the screen once it has been scrolled into view. Uses `elementIdLocationInView` protocol command. * - * Usage: - * ``` - * this.demoTest = function (client) { - * client.getTagName("#main ul li .first", function(result) { - * this.assert.equal(typeof result, "object"); - * this.assert.equal(result.status, 0); - * this.assert.equal(result.value, "a"); - * }); - * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The element's tag name, as a lowercase string. - */ - getTagName(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; - - /** - * Returns the visible text for the element. Uses elementIdText protocol command. - * - * Usage: - * ``` + * @example * this.demoTest = function (browser) { - * browser.getText("#main ul li a.first", function(result) { - * this.assert.equal(typeof result, "object"); - * this.assert.equal(result.status, 0); - * this.assert.equal(result.value, "nightwatchjs.org"); - * }); + * browser.getLocationInView("#main ul li a.first", function(result) { + * this.assert.equal(typeof result, "object"); + * this.assert.equal(result.status, 0); + * this.assert.equal(result.value.x, 200); + * this.assert.equal(result.value.y, 200); + * }); * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The element's visible text. + * + * @see elementIdLocationInView */ - getText(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + getLocationInView(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ x: number; y: number }>) => void): this; /** - * Returns a form element current value. Uses elementIdValue protocol command. + * Query for an element's tag name. Uses `elementIdName` protocol command. * - * Usage: - * ``` + * @example * this.demoTest = function (browser) { - * browser.getValue("form.login input[type=text]", function(result) { - * this.assert.equal(typeof result, "object"); - * this.assert.equal(result.status, 0); - * this.assert.equal(result.value, "enter username"); - * }); + * browser.getTagName("#main ul li .first", function(result) { + * this.assert.equal(typeof result, "object"); + * this.assert.equal(result.status, 0); + * this.assert.equal(result.value, "a"); + * }); * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. - * @returns The element's value. + * + * @see elementIdName */ - getValue(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + getTagName(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; /** - * Determine if an element is currently displayed. Uses elementIdDisplayed protocol command. + * Returns the visible text for the element. Uses `elementIdText` protocol command. * - * Usage: - * ``` + * @example * this.demoTest = function (browser) { - * browser.isVisible('#main', function(result) { - * this.assert.equal(typeof result, "object"); - * this.assert.equal(result.status, 0); - * this.assert.equal(result.value, true); - * }); + * browser.getText("#main ul li a.first", function(result) { + * this.assert.equal(typeof result, "object"); + * this.assert.equal(result.status, 0); + * this.assert.equal(result.value, "nightwatchjs.org"); + * }); * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. + * + * @see elementIdText */ - isVisible(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + getText(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; /** - * Move the mouse by an offset of the specified element. Uses moveTo protocol command. + * Returns a form element current value. Uses `elementIdValue` protocol command. * - * Usage: - * ``` + * @example * this.demoTest = function (browser) { - * browser.moveToElement('#main', 10, 10); + * browser.getValue("form.login input[type=text]", function(result) { + * this.assert.equal(typeof result, "object"); + * this.assert.equal(result.status, 0); + * this.assert.equal(result.value, "enter username"); + * }); * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param xoffset: X offset to move to, relative to the top-left corner of the element. - * @param yoffset: Y offset to move to, relative to the top-left corner of the element. - * @param callback: Optional callback function to be called when the command finishes. + * + * @see elementIdValue */ - moveToElement(selector: string, xoffset: number, yoffset: number, callback?: (result: NightwatchCallbackResult) => void): this; + getValue(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Determine if an element is currently displayed. Uses `elementIdDisplayed` protocol command. + * + * @example + * this.demoTest = function (browser) { + * browser.isVisible('#main', function(result) { + * this.assert.equal(typeof result, "object"); + * this.assert.equal(result.status, 0); + * this.assert.equal(result.value, true); + * }); + * }; + * + * @see elementIdDisplayed + */ + isVisible(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Move the mouse by an offset of the specified element. If an element is provided but no offset, the mouse will be moved to the center of the element. + * If the element is not visible, it will be scrolled into view. + * + * @example + * this.demoTest = function (browser) { + * browser.moveToElement('#main', 10, 10); + * }; + * + * @see moveTo + */ + moveToElement(selector: string, xoffset: number, yoffset: number, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; /** * Sends some text to an element. Can be used to set the value of a form element or to send a sequence of key strokes to an element. Any UTF-8 character may be specified. - * An object map with available keys and their respective UTF-8 characters, as defined on W3C WebDriver draft spec (http://www.w3.org/TR/webdriver/#character-types), - * is loaded onto the main Nightwatch instance as client.Keys. * - * Usage: - * ``` + *
setValue does not clear the existing value of the element. To do so, use the clearValue() command.
+ * + * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), + * is loaded onto the main Nightwatch instance as `browser.Keys`. + * + * @example * // send some simple text to an input * this.demoTest = function (browser) { - * browser.setValue('input[type=text]', 'nightwatch'); + * browser.setValue('input[type=text]', 'nightwatch'); * }; - * * // * // send some text to an input and hit enter. * this.demoTest = function (browser) { - * browser.setValue('input[type=text]', ['nightwatch', browser.Keys.ENTER]); + * browser.setValue('input[type=text]', ['nightwatch', browser.Keys.ENTER]); * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param inputValue: The text to send to the element or key strokes. - * @param callback: Optional callback function to be called when the command finishes. + * + * @see elementIdValue */ - setValue(selector: string, inputValue: string, callback?: () => void): this; + setValue(selector: string, inputValue: string | string[], callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + /** + * Alias for `setValue`. + * @see setValue + */ + sendKeys: SharedCommands["setValue"]; /** - * Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element. Uses submit protocol command. + * Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element. Uses `submit` protocol command. * - * Usage: - * ``` + * @example * this.demoTest = function (browser) { - * browser.submitForm('form.login'); + * browser.submitForm('form.login'); * }; - * ``` - * @param selector: The CSS/Xpath selector used to locate the element. - * @param callback: Optional callback function to be called when the command finishes. + * + * @see submit */ - submitForm(selector: string, callback?: () => void): this; + submitForm(selector: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; /** - * Opposite of waitForElementPresent. Waits a given time in milliseconds for an element to be not present (i.e. removed) in the page before performing any other commands - * or assertions. If the element is still present after the specified amount of time, the test fails. You can change the polling interval by defining - * a waitForConditionPollInterval property (in milliseconds) in as a global property in your nightwatch.json or in your external globals file. - * Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds). + * Opposite of `waitForElementPresent`. Waits a given time in milliseconds for an element to be not present (i.e. removed) + * in the page before performing any other commands or assertions. * - * Usage: - * ``` + * If the element is still present after the specified amount of time, the test fails. + * + * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file. + * + * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds). + * + * @example * this.demoTest = function (browser) { - * browser.waitForElementNotPresent('#dialog', 1000); + * browser.waitForElementNotPresent('#dialog', 1000); * }; - * ``` - * @param selector: The selector (CSS / Xpath) used to locate the element. - * @param time: The number of milliseconds to wait. The runner performs repeated checks every 500 ms. - * @param abortOnFailure: By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. - * To set this globally you can define a property `abortOnNightwatchAssertionsFailure` in your globals. - * @param callback: Optional callback function to be called when the command finishes. - * @param message: Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time - * (e.g. Element %s was not in the page for %d ms). + * + * @see waitForElementPresent + * @since v0.4.0 */ - waitForElementNotPresent(selector: string, time?: number, abortOnFailure?: boolean, callback?: () => void, message?: string): this; + waitForElementNotPresent(selector: string, time?: number, abortOnFailure?: boolean, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void, message?: string): this; /** - * Opposite of waitForElementVisible. Waits a given time in milliseconds for an element to be not visible (i.e. hidden but existing) in the page before performing - * any other commands or assertions. If the element fails to be hidden in the specified amount of time, the test fails. You can change the polling interval by - * defining a waitForConditionPollInterval property (in milliseconds) in as a global property in your nightwatch.json or in your external globals file. - * Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds). + * Opposite of `waitForElementVisible`. Waits a given time in milliseconds for an element to be not visible (i.e. hidden but existing) + * in the page before performing any other commands or assertions. * - * Usage: - * ``` + * If the element fails to be hidden in the specified amount of time, the test fails. + * + * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file. + * + * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds). + * + * @example * this.demoTest = function (browser) { - * browser.waitForElementNotVisible('#dialog', 1000); + * browser.waitForElementNotVisible('#dialog', 1000); * }; - * ``` - * @param selector: The selector (CSS / Xpath) used to locate the element. - * @param time: The number of milliseconds to wait. The runner performs repeated checks every 500 ms. - * @param abortOnFailure: By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. - * To set this globally you can define a property `abortOnNightwatchAssertionsFailure` in your globals. - * @param callback: Optional callback function to be called when the command finishes. - * @param message: Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time - * (e.g. Element %s was not in the page for %d ms). + * + * @since v0.4.0 + * @see waitForElementVisible */ - waitForElementNotVisible(selector: string, time?: number, abortOnFailure?: boolean, callback?: () => void, message?: string): this; + waitForElementNotVisible(selector: string, time?: number, abortOnFailure?: boolean, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void, message?: string): this; /** * Waits a given time in milliseconds for an element to be present in the page before performing any other commands or assertions. - * If the element fails to be present in the specified amount of time, the test fails. You can change this by setting abortOnFailure to false. - * You can change the polling interval by defining a waitForConditionPollInterval property (in milliseconds) in as a global property in your nightwatch.json or in - * your external globals file. - * Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds). * - * Usage: - * ``` + * If the element fails to be present in the specified amount of time, the test fails. You can change this by setting `abortOnFailure` to `false`. + * + * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file. + * + * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds). + * + * @example * this.demoTest = function (browser) { - * browser.waitForElementPresent('body', 1000); - * // continue if failed - * browser.waitForElementPresent('body', 1000, false); - * // with callback - * browser.waitForElementPresent('body', 1000, function() { - * // do something while we're here - * }); - * // custom Spanish message - * browser.waitForElementPresent('body', 1000, 'elemento %s no era presente en %d ms'); - * // many combinations possible - the message is always the last argument - * browser.waitForElementPresent('body', 1000, false, function() {}, 'elemento %s no era presente en %d ms'); + * browser.waitForElementPresent('body', 1000); + * // continue if failed + * browser.waitForElementPresent('body', 1000, false); + * // with callback + * browser.waitForElementPresent('body', 1000, function() { + * // do something while we're here + * }); + * // custom Spanish message + * browser.waitForElementPresent('body', 1000, 'elemento %s no era presente en %d ms'); + * // many combinations possible - the message is always the last argument + * browser.waitForElementPresent('body', 1000, false, function() {}, 'elemento %s no era presente en %d ms'); * }; - * ``` - * @param selector: The selector (CSS / Xpath) used to locate the element. - * @param time: The number of milliseconds to wait. The runner performs repeated checks every 500 ms. - * @param abortOnFailure: By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. - * To set this globally you can define a property `abortOnNightwatchAssertionsFailure` in your globals. - * @param callback: Optional callback function to be called when the command finishes. - * @param message: Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time - * (e.g. Element %s was not in the page for %d ms). */ - waitForElementPresent(selector: string, time?: number, abortOnFailure?: boolean, callback?: () => void, message?: string): this; + waitForElementPresent(selector: string, time?: number, abortOnFailure?: boolean, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void, message?: string): this; /** * Waits a given time in milliseconds for an element to be visible in the page before performing any other commands or assertions. - * If the element fails to be present and visible in the specified amount of time, the test fails. You can change this by setting abortOnFailure to false. - * You can change the polling interval by defining a waitForConditionPollInterval property (in milliseconds) in as a global property in your nightwatch.json - * or in your external globals file. - * Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds). * - * Usage: - * ``` + * If the element fails to be present and visible in the specified amount of time, the test fails. You can change this by setting `abortOnFailure` to `false`. + * + * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file. + * + * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds). + * + * @example * this.demoTest = function (browser) { - * browser.waitForElementVisible('body', 1000); - * // continue if failed - * browser.waitForElementVisible('body', 1000, false); - * // with callback - * browser.waitForElementVisible('body', 1000, function() { - * // do something while we're here - * }); - * // custom Spanish message - * browser.waitForElementVisible('body', 1000, 'elemento %s no era visible en %d ms'); - * // many combinations possible - the message is always the last argument - * browser.waitForElementVisible('body', 1000, false, function() {}, 'elemento %s no era visible en %d ms'); + * browser.waitForElementVisible('body', 1000); + * // continue if failed + * browser.waitForElementVisible('body', 1000, false); + * // with callback + * browser.waitForElementVisible('body', 1000, function() { + * // do something while we're here + * }); + * // custom Spanish message + * browser.waitForElementVisible('body', 1000, 'elemento %s no era visible en %d ms'); + * // many combinations possible - the message is always the last argument + * browser.waitForElementVisible('body', 1000, false, function() {}, 'elemento %s no era visible en %d ms'); * }; - * ``` - * @param selector: The selector (CSS / Xpath) used to locate the element. - * @param time: The number of milliseconds to wait. The runner performs repeated checks every 500 ms. - * @param abortOnFailure: By the default if the element is not found the test will fail. - * Set this to false if you wish for the test to continue even if the assertion fails. - * To set this globally you can define a property `abortOnNightwatchAssertionsFailure` in your globals. - * @param callback: Optional callback function to be called when the command finishes. - * @param message: Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms). */ - waitForElementVisible(selector: string, time?: number, abortOnFailure?: boolean, callback?: () => void, message?: string): this; + waitForElementVisible(selector: string, time?: number, abortOnFailure?: boolean, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void, message?: string): this; +} + +export interface WebDriverProtocol extends + WebDriverProtocolSessions, WebDriverProtocolNavigation, + WebDriverProtocolCommandContexts, + WebDriverProtocolElements, WebDriverProtocolElementState, + WebDriverProtocolElementInteraction, WebDriverProtocolElementLocation, + WebDriverProtocolDocumentHandling, WebDriverProtocolCookies, + WebDriverProtocolUserActions, WebDriverProtocolUserPrompts, + WebDriverProtocolScreenCapture, WebDriverProtocolMobileRelated { } + +export interface WebDriverProtocolSessions { + /** + * Get info about, delete or create a new session. Defaults to the current session. + * + * @example + * this.demoTest = function (browser) { + * browser.session(function(result) { + * console.log(result.value); + * }); + * // + * browser.session('delete', function(result) { + * console.log(result.value); + * }); + * // + * browser.session('delete', '12345-abc', function(result) { + * console.log(result.value); + * }); + * } + */ + session(action?: string, sessionId?: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult>) => void): this; + + /** + * Returns a list of the currently active sessions. + * + * @example + * this.demoTest = function (browser) { + * browser.sessions(function(result) { + * console.log(result.value); + * }); + * } + */ + sessions(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult>>) => void): this; + + /** + * Configure the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client. + * + * @example + * this.demoTest = function (browser) { + * browser.timeouts('script', 10000, function(result) { + * console.log(result); + * }); + * } + */ + timeouts(typeOfOperation: string, ms: number, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Set the amount of time, in milliseconds, that asynchronous scripts executed by `.executeAsync` are permitted to run before they are aborted and a |Timeout| error is returned to the client. + * + * @example + * this.demoTest = function (browser) { + * browser.timeoutsAsyncScript(10000, function(result) { + * console.log(result); + * }); + * } + */ + timeoutsAsyncScript(ms: number, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Set the amount of time the driver should wait when searching for elements. If this command is never sent, the driver will default to an implicit wait of 0ms. + * + * @example + * this.demoTest = function (browser) { + * browser.timeoutsImplicitWait(10000, function(result) { + * console.log(result); + * }); + * } + */ + timeoutsImplicitWait(ms: number, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Query the server's current status. + */ + status(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ + build: { version: string; revision: string; time: string }; + status: { arch: string; name: string; version: string }; + }>) => void): this; + + /** + * Gets the text of the log type specified. To find out the available log types, use `.getLogTypes()`. + * + * Returns a [log entry JSON object](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#log-entry-json-object). + * + * @example + * this.demoTest = function (browser) { + * browser.sessionLog('client', function(result) { + * console.log(result.value); + * }); + * } + */ + sessionLog(typeString: string, callback?: (this: NightwatchAPI, log: NightwatchLogEntry[]) => void): this; + + /** + * Gets an array of strings for which log types are available. This methods returns the entire WebDriver response, if you are only interested in the logs array, use `.getLogTypes()` instead. + * + * @example + * this.demoTest = function (browser) { + * browser.sessionLogTypes(function(result) { + * console.log(result.value); + * }); + * } + */ + sessionLogTypes(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult>) => void): this; +} + +export interface WebDriverProtocolNavigation { + /** + * Retrieve the URL of the current page or navigate to a new URL. + * + * @example + * module.exports = { + * 'demo Test' : function(browser) { + * browser.url(function(result) { + * // return the current url + * console.log(result); + * }); + * // + * // navigate to new url: + * browser.url('{URL}'); + * // + * // + * // navigate to new url: + * browser.url('{URL}', function(result) { + * console.log(result); + * }); + * } + * } + */ + url(url: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + /** + * Retrieve the URL of the current page or navigate to a new URL. + * + * @example + * module.exports = { + * 'demo Test' : function(browser) { + * browser.url(function(result) { + * // return the current url + * console.log(result); + * }); + * // + * // navigate to new url: + * browser.url('{URL}'); + * // + * // + * // navigate to new url: + * browser.url('{URL}', function(result) { + * console.log(result); + * }); + * } + * } + */ + url(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Navigate backwards in the browser history, if possible. + */ + back(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Navigate forwards in the browser history, if possible. + */ + forward(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Refresh the current page. + */ + refresh(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Get the current page title. + * + * @example + * this.demoTest = function (browser) { + * browser.title(function(result) { + * console.log(result.value); + * }); + * } + */ + title(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; +} + +export interface WebDriverProtocolCommandContexts { + /** + * Change focus to another window or close the current window. Shouldn't normally be used directly, instead `.switchWindow()` and `.closeWindow()` should be used. + */ + window(method: string, handleOrName?: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Retrieve the current window handle. + * + * @example + * this.demoTest = function (browser) { + * browser.windowHandle(function(result) { + * console.log(result.value); + * }); + * } + */ + windowHandle(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Retrieve the list of all window handles available to the session. + * + * @example + * this.demoTest = function (browser) { + * browser.windowHandles(function(result) { + * // An array of window handles. + * console.log(result.value); + * }); + * } + */ + windowHandles(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Increases the window to the maximum available size without going full-screen. + * + * @example + * this.demoTest = function (browser) { + * browser.windowMaximize('current', function(result) { + * console.log(result); + * }); + * } + */ + windowMaximize(handleOrName: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Change or get the position of the specified window. If the second argument is a function it will be used as a callback and + * the call will perform a get request to retrieve the existing window position. + * + * @example + * this.demoTest = function (browser) { + * + * // Change the position of the specified window. + * // If the :windowHandle URL parameter is "current", the currently active window will be moved. + * browser.windowPosition('current', 0, 0, function(result) { + * console.log(result); + * }); + * + * // Get the position of the specified window. + * // If the :windowHandle URL parameter is "current", the position of the currently active window will be returned. + * browser.windowPosition('current', function(result) { + * console.log(result.value); + * }); + * } + */ + windowPosition(windowHandle: string, offsetX: number, offsetY: number, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + /** + * Change or get the position of the specified window. If the second argument is a function it will be used as a callback and + * the call will perform a get request to retrieve the existing window position. + * + * @example + * this.demoTest = function (browser) { + * + * // Change the position of the specified window. + * // If the :windowHandle URL parameter is "current", the currently active window will be moved. + * browser.windowPosition('current', 0, 0, function(result) { + * console.log(result); + * }); + * + * // Get the position of the specified window. + * // If the :windowHandle URL parameter is "current", the position of the currently active window will be returned. + * browser.windowPosition('current', function(result) { + * console.log(result.value); + * }); + * } + */ + windowPosition(windowHandle: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ x: number; y: number }>) => void): this; + + /** + * Change or get the size of the specified window. If the second argument is a function it will be used as a callback and the call will perform a get request to retrieve the existing window size. + * + * @example + * this.demoTest = function (browser) { + * + * // Return the size of the specified window. If the :windowHandle URL parameter is "current", the size of the currently active window will be returned. + * browser.windowSize('current', function(result) { + * console.log(result.value); + * }); + * + * // Change the size of the specified window. + * // If the :windowHandle URL parameter is "current", the currently active window will be resized. + * browser.windowSize('current', 300, 300, function(result) { + * console.log(result.value); + * }); + * } + */ + windowSize(windowHandle: string, width: number, height: number, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + /** + * Change or get the size of the specified window. If the second argument is a function it will be used as a callback and the call will perform a get request to retrieve the existing window size. + * + * @example + * this.demoTest = function (browser) { + * + * // Return the size of the specified window. If the :windowHandle URL parameter is "current", the size of the currently active window will be returned. + * browser.windowSize('current', function(result) { + * console.log(result.value); + * }); + * + * // Change the size of the specified window. + * // If the :windowHandle URL parameter is "current", the currently active window will be resized. + * browser.windowSize('current', 300, 300, function(result) { + * console.log(result.value); + * }); + * } + */ + windowSize(windowHandle: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ width: number; height: number }>) => void): this; + + /** + * Change focus to another frame on the page. If the frame id is missing or null, the server should switch to the page's default content. + * + * @example + * this.demoTest = function (browser) { + * browser.frame('', function(result) { + * console.log(result); + * }); + * } + */ + frame(frameId: string | undefined | null, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Change focus to the parent context. If the current context is the top level browsing context, the context remains unchanged. + * + * @example + * this.demoTest = function (browser) { + * browser.frameParent(function(result) { + * console.log(result); + * }); + * } + * + * @since v0.4.8 + */ + frameParent(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; +} + +export interface WebDriverProtocolElements { + /** + * Search for an element on the page, starting from the document root. The located element will be returned as a web element JSON object. + * First argument to be passed is the locator strategy, which is detailed on the [WebDriver docs](https://www.w3.org/TR/webdriver/#locator-strategies). + * + * The locator stragy can be one of: + * - `css selector` + * - `link text` + * - `partial link text` + * - `tag name` + * - `xpath` + * + * @example + * module.exports = { + * 'demo Test' : function(browser) { + * browser.element('css selector', 'body', function(result) { + * console.log(result.value) + * }); + * }, + * + * 'es6 async demo Test': async function(browser) { + * const result = await browser.element('css selector', 'body'); + * console.log('result value is:', result.value); + * } + * } + */ + element(using: LocateStrategy, value: string, callback: (this: NightwatchAPI, result: NightwatchCallbackResult<{ ELEMENT: string }>) => void): this; + + /** + * Search for multiple elements on the page, starting from the document root. The located elements will be returned as web element JSON objects. + * First argument to be passed is the locator strategy, which is detailed on the [WebDriver docs](https://www.w3.org/TR/webdriver/#locator-strategies). + * + * * The locator strategy can be one of: + * - `css selector` + * - `link text` + * - `partial link text` + * - `tag name` + * - `xpath` + * + * @example + * module.exports = { + * 'demo Test' : function(browser) { + * browser.elements('css selector', 'ul li', function(result) { + * console.log(result.value) + * }); + * }, + * + * 'es6 async demo Test': async function(browser) { + * const result = await browser.elements('css selector', 'ul li'); + * console.log('result value is:', result.value); + * }, + * + * 'page object demo Test': function (browser) { + * var nightwatch = browser.page.nightwatch(); + * nightwatch + * .navigate() + * .assert.titleContains('Nightwatch.js'); + * + * nightwatch.api.elements('@featuresList', function(result) { + * console.log(result); + * }); + * + * browser.end(); + * } + * } + */ + elements(using: LocateStrategy, value: string, callback: (this: NightwatchAPI, result: NightwatchCallbackResult>) => void): this; + + /** + * Search for an element on the page, starting from the identified element. The located element will be returned as a Web Element JSON object. + * + * This command operates on a protocol level and requires a [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements). + * Read more on [Element retrieval](https://www.w3.org/TR/webdriver1/#element-retrieval) on the W3C WebDriver spec page. + * + * @example + * module.exports = { + * 'demo Test' : function(browser) { + * browser.elementIdElement('', 'css selector', '.new-element', function(result) { + * console.log(result.value) + * }); + * }, + * + * 'es6 async demo Test': async function(browser) { + * const result = await browser.elementIdElement('', 'css selector', '.new-element'); + * console.log(result.value); + * } + * } + */ + elementIdElement(id: string, using: LocateStrategy, value: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ ELEMENT: string }>) => void): this; + + /** + * Search for multiple elements on the page, starting from the identified element. The located element will be returned as a web element JSON objects. + * + * @example + * module.exports = { + * 'demo Test' : function(browser) { + * browser.elementIdElements('', 'css selector', 'ul li', function(result) { + * console.log(result.value) + * }); + * }, + * + * 'es6 async demo Test': async function(browser) { + * const result = await browser.elementIdElements('', 'css selector', 'ul li'); + * console.log(result.value); + * } + * } + */ + elementIdElements(id: string, using: LocateStrategy, value: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult>) => void): this; + + /** + * Test if two web element IDs refer to the same DOM element. + * + * This command is __deprecated__ and is only available on the [JSON Wire protocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidelementidequalsother) + * + * @example + * module.exports = { + * 'demo Test' : function(browser) { + * browser.elementIdEquals('', '', function(result) { + * console.log(result.value) + * }); + * } + * } + */ + elementIdEquals(id: string, otherId: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Get the element on the page that currently has focus. The element will be returned as a [Web Element](https://www.w3.org/TR/webdriver1/#dfn-web-elements) JSON object. + * + * @example + * module.exports = { + * 'demo Test' : function(browser) { + * browser.elementActive(function(result) { + * console.log(result.value) + * }); + * } + * } + */ + elementActive(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ ELEMENT: string }>) => void): this; +} + +export interface WebDriverProtocolElementState { + /** + * Get the value of an element's attribute. + */ + elementIdAttribute(id: string, attributeName: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Retrieve the computed value of the given CSS property of the given element. + * + * The CSS property to query should be specified using the CSS property name, not the JavaScript property name (e.g. background-color instead of backgroundColor). + */ + elementIdCssProperty(id: string, cssPropertyName: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Determine if an element is currently displayed. + */ + elementIdDisplayed(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Determine if an element is currently enabled. + */ + elementIdEnabled(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Retrieve the qualified tag name of the given element. + */ + elementIdName(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Determine if an OPTION element, or an INPUT element of type checkbox or radio button is currently selected. + */ + elementIdSelected(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Determine an element's size in pixels. The size will be returned as a JSON object with width and height properties. + */ + elementIdSize(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ width: number; height: number }>) => void): this; + + /** + * Returns the visible text for the element. + */ + elementIdText(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; +} + +export interface WebDriverProtocolElementInteraction { + /** + * Scrolls into view a submittable element excluding buttons or editable element, and then attempts to clear its value, reset the checked state, or text content. + */ + elementIdClear(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Scrolls into view the element and clicks the in-view center point. If the element is not pointer-interactable, an element not interactable error is returned. + */ + elementIdClick(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Scrolls into view the form control element and then sends the provided keys to the element, or returns the current value of the element. + * In case the element is not keyboard interactable, an element not interactable error is returned. + */ + elementIdValue(id: string, value: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + /** + * Scrolls into view the form control element and then sends the provided keys to the element, or returns the current value of the element. + * In case the element is not keyboard interactable, an element not interactable error is returned. + */ + elementIdValue(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Send a sequence of key strokes to the active element. The sequence is defined in the same format as the `sendKeys` command. + * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), + * is loaded onto the main Nightwatch instance as `client.Keys`. + * + * Rather than the `setValue`, the modifiers are not released at the end of the call. The state of the modifier keys is kept between calls, + * so mouse interactions can be performed while modifier keys are depressed. + */ + keys(keysToSend: string[], callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element. + */ + submit(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; +} + +export interface WebDriverProtocolElementLocation { + /** + * Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page. + * + * The element's coordinates are returned as a JSON object with x and y properties. + */ + elementIdLocation(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ x: number; y: number }>) => void): this; + + /** + * Determine an element's location on the screen once it has been scrolled into view. + */ + elementIdLocationInView(id: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<{ x: number; y: number }>) => void): this; +} + +export interface WebDriverProtocolDocumentHandling { + /** + * Returns a string serialisation of the DOM of the current page. + */ + source(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous. + * The script argument defines the script to execute in the form of a function body. The value returned by that function will be returned to the client. + * + * The function will be invoked with the provided args array and the values may be accessed via the arguments object in the order specified. + * + * Under the hood, if the `body` param is a function it is converted to a string with `.toString()`. Any references to your current scope are ignored. + * + * To ensure cross-browser compatibility, the specified function should not be in ES6 format (i.e. `() => {}`). + * If the execution of the function fails, the first argument of the callback contains error information. + * + * @example + * this.demoTest = function (browser) { + * browser.execute(function(imageData) { + * // resize operation + * return true; + * }, [imageData], function(result) { + * // result.value === true + * }); + * } + */ + execute(body: ((this: undefined, ...data: any[]) => T) | string, args?: any[], callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be asynchronous. + * + * The function to be injected receives the `done` callback as argument which needs to be called when the asynchronous operation finishes. + * The value passed to the `done` callback is returned to the client. + * Additional arguments for the injected function may be passed as a non-empty array which will be passed before the `done` callback. + * + * Asynchronous script commands may not span page loads. If an unload event is fired while waiting for the script result, an error will be returned. + * + * @example + * this.demoTest = function (browser) { + * browser.executeAsync(function(done) { + * setTimeout(function() { + * done(true); + * }, 500); + * }, function(result) { + * // result.value === true + * }); + * + * browser.executeAsync(function(arg1, arg2, done) { + * setTimeout(function() { + * done(true); + * }, 500); + * }, [arg1, arg2], function(result) { + * // result.value === true + * }); + * } + */ + executeAsync(script: ((this: undefined, ...data: any[]) => T) | string, args?: any[], callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; +} + +export interface WebDriverProtocolCookies { + /** + * Retrieve or delete all cookies visible to the current page or set a cookie. Normally this shouldn't be used directly, instead the cookie convenience methods should be used: + * getCookie, getCookies, setCookie, deleteCookie, deleteCookies. + * + * @see getCookies + * @see getCookie + * @see setCookie + * @see deleteCookie + * @see deleteCookies + */ + cookie(method: string, callbackOrCookie?: () => void): this; +} + +export interface WebDriverProtocolUserActions { + /** + * Double-clicks at the current mouse coordinates (set by `.moveTo()`). + */ + doubleClick(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Click at the current mouse coordinates (set by `.moveTo()`). + * + * The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button. + */ + mouseButtonClick(button: 0 | 1 | 2 | 'left' | 'middle' | 'right', callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Click and hold the left mouse button (at the coordinates set by the last `moveTo` command). Note that the next mouse-related command that should follow is `mouseButtonUp` . + * Any other mouse command (such as click or another call to buttondown) will yield undefined behaviour. + * + * Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button, + * and if you don't pass in a button but do pass in a callback, it will handle it correctly. + */ + mouseButtonDown(button: 0 | 1 | 2 | 'left' | 'middle' | 'right', callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Releases the mouse button previously held (where the mouse is currently at). Must be called once for every `mouseButtonDown` command issued. + * + * Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button, + * and if you don't pass in a button but do pass in a callback, it will handle it correctly. + */ + mouseButtonUp(button: 0 | 1 | 2 | 'left' | 'middle' | 'right', callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Move the mouse by an offset of the specified [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) or relative to the current mouse cursor, if no element is specified. + * If an element is provided but no offset, the mouse will be moved to the center of the element. + * + * If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view. + * + * @example + * this.demoTest = function (browser) { + * browser.moveTo(null, 110, 100); + * }; + */ + moveTo(element: string | null, xoffset: number, yoffset: number, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; +} + +export interface WebDriverProtocolUserPrompts { + /** + * Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog. + */ + acceptAlert(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Dismisses the currently displayed alert dialog. For confirm() and prompt() dialogs, this is equivalent to clicking the 'Cancel' button. + * + * For alert() dialogs, this is equivalent to clicking the 'OK' button. + */ + dismissAlert(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Gets the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog. + */ + getAlertText(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Sends keystrokes to a JavaScript prompt() dialog. + */ + setAlertText(value: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; +} + +export interface WebDriverProtocolScreenCapture { + /** + * Take a screenshot of the current page. + */ + screenshot(log_screenshot_data: boolean, callback?: (screenshotEncoded: string) => void): this; +} + +export interface WebDriverProtocolMobileRelated { + /** + * Get the current browser orientation. + */ + getOrientation(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<"LANDSCAPE" | "PORTRAIT">) => void): this; + + /** + * Sets the browser orientation. + */ + setOrientation(orientation: "LANDSCAPE" | "PORTRAIT", callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Get a list of the available contexts. + * + * Used by Appium when testing hybrid mobile web apps. More info here: https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/hybrid.md. + */ + contexts(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Get current context. + */ + currentContext(callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): this; + + /** + * Sets the context. + */ + setContext(context: string, callback?: () => void): this; } diff --git a/types/nightwatch/nightwatch-tests.ts b/types/nightwatch/nightwatch-tests.ts index d77b943cd0..f5030f4146 100644 --- a/types/nightwatch/nightwatch-tests.ts +++ b/types/nightwatch/nightwatch-tests.ts @@ -1,23 +1,295 @@ -import { NightwatchAPI, NightwatchTests } from 'nightwatch'; +import { EventEmitter } from 'events'; +import { EnhancedPageObject, EnhancedSectionInstance, NightwatchAPI, NightwatchAssertion, NightwatchBrowser, NightwatchTests } from 'nightwatch'; -const test: NightwatchTests = { - before: (browser, done) => { - done(); - }, - 'Demo test Google': (browser) => { +// +// ./tests/general.ts +// + +const testGeneral: NightwatchTests = { + 'Demo test Google 1': (browser: NightwatchBrowser) => { browser - .url('http://www.google.com') + .url('https://google.com') + .pause(1000); + + // expect element to be present in 1000ms + browser.expect.element('body').to.be.present.before(1000); + + // expect element <#lst-ib> to have css property 'display' + browser.expect.element('#lst-ib').to.have.css('display'); + + // expect element to have attribute 'class' which contains text 'vasq' + browser.expect.element('body').to.have.attribute('class').which.contains('vasq'); + + // expect element <#lst-ib> to be an input tag + browser.expect.element('#lst-ib').to.be.an('input'); + + // expect element <#lst-ib> to be visible + browser.expect.element('#lst-ib').to.be.visible; + + browser.end(); + }, + + 'Demo test Google 2': (browser: NightwatchBrowser) => { + browser + .url('https://www.google.com') + .waitForElementVisible('body') + .setValue('input[type=text]', 'nightwatch') + .waitForElementVisible('input[name=btnK]') + .click('input[name=btnK]') + .pause(1000) + .assert.containsText('#main', 'Night Watch') + .end(); + }, + + 'step one: navigate to google': (browser: NightwatchBrowser) => { + browser + .url('https://www.google.com') .waitForElementVisible('body', 1000) .setValue('input[type=text]', 'nightwatch') - .waitForElementVisible('button[name=btnG]', 1000) - .getTitle(function(result) { - this.assert.equal(typeof result, 'string'); - }) - .click('button[name=btnG]') + .waitForElementVisible('input[name=btnK]', 1000); + }, + + 'step two: click input': (browser: NightwatchBrowser) => { + browser + .click('input[name=btnK]') .pause(1000) .assert.containsText('#main', 'Night Watch') .end(); } }; -export = test; +// +// ./pages/google.ts +// + +const appsSection = { + selector: 'div.gb_qc', + commands: [{ + clickYoutube(this: AppsSection) { + return this.click('@youtube'); + } + }], + elements: { + myAccount: { + selector: '#gb192' + }, + youtube: { + selector: '#gb36' + } + }, +}; + +interface AppsSection extends EnhancedSectionInstance { } + +const menuSection = { + selector: '#gb', + commands: [{ + // add section commands here + clickApps(this: MenuSection) { + return this.click('@appSection'); + } + }], + elements: { + mail: { + selector: 'a[href="mail"]' + }, + images: { + selector: 'a[href="imghp"]' + } + }, + sections: { + apps: appsSection + } +}; + +interface MenuSection extends EnhancedSectionInstance { } + +const googlePage = { + commands: [{ + submit(this: GooglePage) { + this.api.pause(1000); + return this.waitForElementVisible('@submitButton', 1000) + .click('@submitButton') + .waitForElementNotPresent('@submitButton'); + } + }], + elements: { + searchBar: { + selector: 'input[type=text]' + }, + submitButton: { + selector: 'input[name=btnK]' + } + }, + sections: { + menu: menuSection + } +}; + +// export = googlePage; + +interface GooglePage extends EnhancedPageObject { } + +declare module 'nightwatch' { + interface NightwatchCustomPageObjects { + google(): GooglePage; + } +} + +const testPage = { + 'Test commands': (browser: NightwatchBrowser) => { + const google = browser.page.google(); + google + .setValue('@searchBar', 'nightwatch') + .submit(); + + browser.end(); + }, + + 'Test sections': (browser: NightwatchBrowser) => { + const google = browser.page.google(); + + const menuSection = google.section.menu; + menuSection.expect.element('@mail').to.be.visible; + menuSection.expect.element('@images').to.be.visible; + + menuSection.clickApps(); + + const appSection = menuSection.section.apps; + appSection.expect.element('@myAccount').to.be.visible; + appSection.expect.element('@youtube').to.be.visible; + + appSection.clickYoutube(); + + browser.end(); + }, + + 'Test assertions on page': (browser: NightwatchBrowser) => { + const google = browser.page.google(); + + google.navigate() + .assert.title('Google') + .assert.visible('@searchBar') + .setValue('@searchBar', 'nightwatch') + .click('@submit'); + + browser.end(); + } +}; + +// +// ./commands/localStorageValue.ts +// - function based command +// + +function localStorageValueCommand(this: NightwatchAPI, key: string, callback?: (value: string | null) => void) { + const self = this; + + this.execute( + // tslint:disable-next-line + function(key) { + return window.localStorage.getItem(key); + }, + [key], // arguments array to be passed + (result) => { + if (result.status) { + throw result.value; + } + if (typeof callback === 'function') { + callback.call(self, result.value); + } + }); + + return this; +} + +declare module 'nightwatch' { + interface NightwatchCustomCommands { + localStorageValue(key: string, callback?: (value: string | null) => void): this; + } +} + +// module.exports.command = resizeCommand; + +const testCustomCommandFunction = { + 'Test command function': (browser: NightwatchBrowser) => { + browser.localStorageValue('my-key', (result) => { + console.log(result); + }); + } +}; + +// +// ./commands/consoleLog.ts +// - class based command +// + +class ConsoleLog extends EventEmitter { + command(this: ConsoleLog & NightwatchAPI, message: string, ...args: any[]) { + setTimeout(() => { + console.log(message, ...args); + this.emit('complete'); + }, 1); + + return this; + } +} + +declare module 'nightwatch' { + interface NightwatchCustomCommands { + consoleLog(message: string, ...args: any[]): this; + } +} + +// module.exports = ConsoleLog; + +const testCustomCommandClass = { + 'Test command class': (browser: NightwatchBrowser) => { + browser.consoleLog('Hello world!'); + } +}; + +// +// ./assertions/text.ts +// + +function text(this: NightwatchAssertion, selector: string, expectedText: string, msg?: string) { + this.expected = expectedText; + + this.message = msg || `Element <${selector}> has text ${this.expected}.`; + + this.pass = value => value === expectedText; + + this.value = result => result; + + this.command = function(callback) { + this.api.element('css selector', selector, elementResult => { + if (elementResult.status) { + callback(null); + return; + } + this.api.elementIdText(elementResult.value.ELEMENT, textResult => { + if (textResult.status) { + callback(null); + return; + } + callback(textResult.value); + }); + }); + return this; + }; +} + +// exports.assertion = text; + +declare module 'nightwatch' { + interface NightwatchCustomAssertions { + text: (selector: string, expectedText: string, msg?: string) => NightwatchAPI; + } +} + +const testCustomAssertion = { + 'Test custom assertion': (browser: NightwatchBrowser) => { + browser.assert.text('#checkme', 'Exactly match text'); + } +};