Skip to content

Commit

Permalink
Allow WebElement as a possible selector in type declarations. (#3896)
Browse files Browse the repository at this point in the history
  • Loading branch information
garg3133 authored Aug 30, 2023
1 parent 649dc84 commit 8ae7e0a
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 30 deletions.
6 changes: 3 additions & 3 deletions types/assertions.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {NightwatchCustomAssertions} from './custom-assertion';
import {Awaitable, Definition, ElementResult, JSON_WEB_OBJECT} from './index';
import {Awaitable, Definition, ElementResult, JSON_WEB_OBJECT, ScopedSelector} from './index';
import { IfUnknown } from './utils';

export interface NightwatchAssertionsError {
Expand Down Expand Up @@ -124,7 +124,7 @@ export interface NightwatchCommonAssertions<ReturnType> {
*
*/
elementsCount(
selector: Definition,
selector: ScopedSelector,
count: number,
msg?: string
): Awaitable<
Expand All @@ -144,7 +144,7 @@ export interface NightwatchCommonAssertions<ReturnType> {
* ```
*/
elementPresent(
selector: Definition,
selector: ScopedSelector,
msg?: string
): Awaitable<
IfUnknown<ReturnType, this>,
Expand Down
4 changes: 2 additions & 2 deletions types/custom-assertion.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ interface NightwatchAssertionFailedResult<T> {

/**
* @example
* import {Definition, NightwatchAssertion} from 'nightwatch';
* import {ScopedSelector, NightwatchAssertion} from 'nightwatch';
*
* export const assertion = function ElementHasCount(this: NightwatchAssertion<number>, selector: Definition, count: number) {
* export const assertion = function ElementHasCount(this: NightwatchAssertion<number>, selector: ScopedSelector, count: number) {
* this.message = `Testing if element <${selector}> has count: ${count}`;
*
* this.expected = count;
Expand Down
10 changes: 5 additions & 5 deletions types/expect.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { By, WebElement } from 'selenium-webdriver';
import {Definition, NightwatchAPI, Awaitable, Element, ELEMENT_KEY} from './index';
import {Definition, NightwatchAPI, Awaitable, Element, ELEMENT_KEY, ScopedSelector} from './index';

export interface NightwatchExpectResult {
value: null;
Expand Down Expand Up @@ -196,23 +196,23 @@ export interface Expect {
/**
* Expect assertions operating on a single element, specified by its CSS/Xpath selector.
*/
element(property: Definition | WebElement): ExpectElement;
element(property: Definition): ExpectElement;

/**
* Expect assertions operating on a single component.
*/
component(property: Definition | WebElement): ExpectElement;
component(property: Definition): ExpectElement;

/**
* Expect assertions operating on a page-object section, specified by '`@section_name`'.
*/
section(property: Definition): ExpectSection;
section(property: ScopedSelector): ExpectSection;

/**
* Expect assertions operating on a collection of elements, specified by a CSS/Xpath selector.
* So far only .count is available.
*/
elements(property: Definition): ExpectElements;
elements(property: ScopedSelector): ExpectElements;

/**
* Retrieves the page title value in order to be used for performing equal, match or contains assertions on it.
Expand Down
23 changes: 13 additions & 10 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ export interface JSON_WEB_OBJECT extends ElementResult {
getId: () => string;
}

export type Definition = string | ElementProperties | Element | SeleniumBy | RelativeBy;
export type ScopedSelector = string | ElementProperties | Element | SeleniumBy | RelativeBy;
export type Definition = ScopedSelector | WebElement;

export type Awaitable<T, V> = Omit<T, 'then'> & PromiseLike<V>;

Expand Down Expand Up @@ -687,6 +688,8 @@ export class Element {
timeout?: number;
}

type ElementGlobalDefinition = string | SeleniumBy | RelativeBy | {selector: string; locateStrategy?: string} | {using: string, value: string};

export interface ElementGlobal extends Element {
/**
* Get the server-assigned opaque ID assigned to this element.
Expand All @@ -698,24 +701,24 @@ export interface ElementGlobal extends Element {
/**
* Locates the descendants of this element that match the given search criteria, and returns the first one.
*
* If no `selector` is passed, returns the[WebElement](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html)
* If no `selector` is passed, returns the [WebElement](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html)
* instance for this element.
*/
findElement(): Awaitable<NightwatchAPI, WebElement>;
findElement(
selector: Definition,
selector: ElementGlobalDefinition,
callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<WebElement>) => void
): Awaitable<NightwatchAPI, WebElement>;

/**
* Locates and wraps the first element, that match the given search criteria in the descendants of this element, in global element() api object.
*
* If no `selector` is passed, returns the[WebElement](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html)
* If no `selector` is passed, returns the [WebElement](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html)
* instance for this element.
*/
find(): Awaitable<NightwatchAPI, WebElement>;
find(
selector: Definition,
selector: ElementGlobalDefinition,
callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<ElementGlobal | null>) => void
): Awaitable<NightwatchAPI, ElementGlobal | null>;

Expand All @@ -726,12 +729,12 @@ export interface ElementGlobal extends Element {
* Locates all of the descendants of this element that match the given search criteria.
*/
findElements(
selector: Definition,
selector: ElementGlobalDefinition,
callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<WebElement[]>) => void
): Awaitable<NightwatchAPI, WebElement[]>;

findAll(
selector: Definition,
selector: ElementGlobalDefinition,
callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<ElementGlobal[]>) => void
): Awaitable<NightwatchAPI, ElementGlobal[]>;

Expand Down Expand Up @@ -926,7 +929,7 @@ export interface ElementGlobal extends Element {
}

export function globalElement(
locator: Definition | WebElement,
locator: Definition,
options?: {
isComponent?: boolean;
type: string;
Expand Down Expand Up @@ -4173,15 +4176,15 @@ export interface ElementCommands {
* @see https://nightwatchjs.org/api/getShadowRoot.html
*/
getShadowRoot(
selector: Definition | WebElement,
selector: Definition,
callback?: (
this: NightwatchAPI,
result: NightwatchCallbackResult<ElementGlobal | null>
) => void
): Awaitable<this, ElementGlobal | null>;
getShadowRoot(
using: LocateStrategy,
selector: Definition | WebElement,
selector: Definition,
callback?: (
this: NightwatchAPI,
result: NightwatchCallbackResult<ElementGlobal | null>
Expand Down
38 changes: 32 additions & 6 deletions types/page-object.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {

export interface SectionProperties {
/**
* The element selector name
* The selector string to be used to find the section in the DOM.
*
* @example
* sections: {
Expand All @@ -30,6 +30,19 @@ export interface SectionProperties {
*/
selector: string;

/**
* The locate strategy to be used with `selector` when finding the section within the DOM.
* - css selector
* - link text
* - partial link text
* - tag name
* - xpath
*
* @example
* 'css selector'
*/
locateStrategy?: LocateStrategy;

/**
* An object, or array of objects, of named element definitions to be used
* as element selectors within element commands.
Expand Down Expand Up @@ -196,12 +209,25 @@ export interface EnhancedPageObjectSections<
Props
> {
/**
* The element selector name
* The selector string used to find the section in the DOM.
*
* @example
* '@searchBar'
* '#searchBar'
*/
selector: string;

/**
* The locate strategy used with `selector` when finding the section within the DOM.
* - css selector
* - link text
* - partial link text
* - tag name
* - xpath
*
* @example
* 'css selector'
*/
locateStrategy: LocateStrategy;
}

interface EnhancedPageObjectSharedFields<
Expand Down Expand Up @@ -272,15 +298,15 @@ interface EnhancedPageObjectSharedFields<

export interface ElementProperties {
/**
* The element selector name
* The selector string to be used to find the element in the DOM.
*
* @example
* '@searchBar'
* '#searchBar'
*/
selector: string;

/**
* locator strategy can be one of
* The locate strategy to be used with `selector` when finding the element within the DOM.
* - css selector
* - link text
* - partial link text
Expand Down
12 changes: 11 additions & 1 deletion types/tests/globalElementApi.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expectAssignable, expectType } from "tsd";
import { expectAssignable, expectError, expectType } from "tsd";
import { ElementGlobal, NightwatchAPI, NightwatchCallbackResult, NightwatchSizeAndPosition } from "..";
import { WebElement } from "selenium-webdriver";

Expand Down Expand Up @@ -55,6 +55,16 @@ describe('global element() api', function () {
}));
expectType<ElementGlobal | null>(await elem.find('child-selector'));

elem.find({using: 'css selector', value: 'child-selector'});
expectError(elem.find({value: 'child-selector'}));
expectError(elem.find({using: 'css selector', value: 'child-selector', abortOnFailure: true}));

const elemProp = {locateStrategy: 'css selector', selector: 'child-selector', abortOnFailure: true};
elem.find(elemProp);
expectError(elem.find({locateStrategy: 'css selector', selector: 'child-selector', abortOnFailure: true}));

expectError(elem.find({locateStrategy: 'css selector', value: 'child-selector'}));

// .get()
expectAssignable<NightwatchAPI>(elem.get());
expectType<WebElement>(await elem.get());
Expand Down
10 changes: 9 additions & 1 deletion types/tests/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import {
ElementResult,
Awaitable,
SectionProperties,
ScopedElement
ScopedElement,
LocateStrategy
} from '..';
import { element as elementNamedExport } from '..';
import { WebElement } from 'selenium-webdriver';
Expand Down Expand Up @@ -381,6 +382,7 @@ const appsSection = {

const menuSection = {
selector: '#gb',
locateStrategy: 'css selector',
commands: [
{
// add section commands here
Expand Down Expand Up @@ -507,6 +509,12 @@ const testPage = {

const menuSection = google.section.menu;

expectType<string>(menuSection.selector);
expectType<LocateStrategy>(menuSection.locateStrategy);

google.expect.section('@menu').to.be.visible;
google.expect.section(menuSection).to.be.visible;

const result = menuSection
.assert.visible('@mail')
.assert.visible('@images');
Expand Down
6 changes: 4 additions & 2 deletions types/web-element.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ export interface ScopedElement extends Element, PromiseLike<WebElement> {
}
): ScopedElement;

findAll(selector: ScopedElementSelector): Elements;
getAll(selector: ScopedElementSelector): Elements;
findAll(selector: ScopedSelector | Promise<ScopedSelector>): Elements;
getAll(selector: ScopedSelector | Promise<ScopedSelector>): Elements;

findAllByText(
text: string,
Expand Down Expand Up @@ -167,6 +167,8 @@ export interface ScopedElement extends Element, PromiseLike<WebElement> {

update<E extends readonly unknown[]>(...keys: E): Promise<WebElement>;

upload(file: string): Promise<WebElement>;

getAccessibleName(): ElementValue<string>;

getAriaRole(): ElementValue<string>;
Expand Down

0 comments on commit 8ae7e0a

Please sign in to comment.