diff --git a/types/clerk.io/clerk.io-tests.ts b/types/clerk.io/clerk.io-tests.ts index c07b7cf7116340..0a37ec972db500 100644 --- a/types/clerk.io/clerk.io-tests.ts +++ b/types/clerk.io/clerk.io-tests.ts @@ -1,3 +1,5 @@ +import { ConfigTypes, ResponseTypes } from "clerk.io"; + if (window.Clerk) { // @ts-expect-error window.Clerk("click", 1); @@ -31,4 +33,19 @@ if (window.Clerk) { content.element; // $ExpectType HTMLElement content.more(5); }); + + // Test that newly exported ConfigTypes are accessible + const searchConfig: ConfigTypes["search/search"] = { + key: "test-key", + query: "test", + limit: 10, + }; + + // Test that newly exported ResponseTypes are accessible + const searchResponse: ResponseTypes["search/search"] = { + result: ["product1", "product2"], + count: 2, + facets: null, + status: "ok", + }; } diff --git a/types/clerk.io/index.d.ts b/types/clerk.io/index.d.ts index 1ddc5d639aae1f..7fec3b791ab0d2 100644 --- a/types/clerk.io/index.d.ts +++ b/types/clerk.io/index.d.ts @@ -1,6 +1,12 @@ import * as Config from "./types/config"; +import * as Helpers from "./types/helpers"; import * as Response from "./types/response"; +// Re-export all types from submodules for direct access +export * from "./types/config"; +export * from "./types/helpers"; +export * from "./types/response"; + export {}; export interface InitConfig { diff --git a/types/clerk.io/tsconfig.json b/types/clerk.io/tsconfig.json index 58f44e40845a6f..5f864a8ccf310a 100644 --- a/types/clerk.io/tsconfig.json +++ b/types/clerk.io/tsconfig.json @@ -16,8 +16,8 @@ "files": [ "index.d.ts", "clerk.io-tests.ts", - "types/helpers.ts", - "types/config.ts", - "types/response.ts" + "types/helpers.d.ts", + "types/config.d.ts", + "types/response.d.ts" ] } diff --git a/types/clerk.io/types/config.ts b/types/clerk.io/types/config.d.ts similarity index 96% rename from types/clerk.io/types/config.ts rename to types/clerk.io/types/config.d.ts index 872be051b15dce..5db7e37c8d39b9 100644 --- a/types/clerk.io/types/config.ts +++ b/types/clerk.io/types/config.d.ts @@ -1,7 +1,7 @@ import type { IntRange } from "./helpers"; // Base types -interface BaseConfig { +export interface BaseConfig { key: string; /** * @description Required for tracking. Visitor ID for the given visitor. If auto, an anonymous ID is generated @@ -21,11 +21,11 @@ interface BaseConfig { debug?: boolean; } -type BaseLimitConfig = BaseConfig & { +export type BaseLimitConfig = BaseConfig & { limit: number; }; -type BaseSearchConfig = BaseLimitConfig & { +export type BaseSearchConfig = BaseLimitConfig & { /** * @description Required for tracking - A list of one or more text labels, used to track the labels performance in Analytics */ @@ -45,7 +45,7 @@ type BaseSearchConfig = BaseLimitConfig & { attributes?: string[]; }; -type BaseFacetedConfig = BaseSearchConfig & { +export type BaseFacetedConfig = BaseSearchConfig & { /** * @description List of facets to be returned for the products in the result * @see https://docs.clerk.io/docs/facets diff --git a/types/clerk.io/types/helpers.ts b/types/clerk.io/types/helpers.d.ts similarity index 59% rename from types/clerk.io/types/helpers.ts rename to types/clerk.io/types/helpers.d.ts index b313213d33bd37..e909ce8299a61e 100644 --- a/types/clerk.io/types/helpers.ts +++ b/types/clerk.io/types/helpers.d.ts @@ -1,6 +1,6 @@ -import type { ClerkObject } from "clerk.io"; +import type { ClerkObject } from "../index"; -type Enumerate = Acc["length"] extends N ? Acc[number] +export type Enumerate = Acc["length"] extends N ? Acc[number] : Enumerate; export type IntRange = Exclude, Enumerate>; diff --git a/types/clerk.io/types/response.ts b/types/clerk.io/types/response.d.ts similarity index 94% rename from types/clerk.io/types/response.ts rename to types/clerk.io/types/response.d.ts index efd73397e99d73..cc1c2d38963ec8 100644 --- a/types/clerk.io/types/response.ts +++ b/types/clerk.io/types/response.d.ts @@ -1,23 +1,23 @@ import type { PickAttributes } from "./helpers"; // Base types -interface BaseResponse { +export interface BaseResponse { result: (string | number)[]; status: string; debug?: Record; } -type BaseProductResponse = BaseResponse & { +export type BaseProductResponse = BaseResponse & { product_data?: PickAttributes[]; }; -type BaseCountedResponse = BaseProductResponse & { +export type BaseCountedResponse = BaseProductResponse & { count: number; facets: unknown | null; }; // Common types -interface Category { +export interface Category { children: number[]; description: string; id: number; @@ -28,7 +28,7 @@ interface Category { url: string; } -interface Page { +export interface Page { author: string | null; blog?: string; created_at: number; diff --git a/types/k6/browser/index.d.ts b/types/k6/browser/index.d.ts index eec82da95f543d..2050420f525eff 100644 --- a/types/k6/browser/index.d.ts +++ b/types/k6/browser/index.d.ts @@ -1719,10 +1719,18 @@ export interface Frame { /** * Сreates and returns a new locator for this frame. + * + * @example + * ```js + * const frame = page.frames()[1]; + * const submitButton = frame.locator('button', { hasText: 'Pizza, Please!' }); + * ``` + * * @param selector The selector to use. + * @param options Options to use for filtering. * @returns The new locator. */ - locator(selector: string): Locator; + locator(selector: string, options?: LocatorOptions): Locator; /** * Get the `innerHTML` attribute of the first element found that matches the selector. @@ -1961,132 +1969,859 @@ export interface Frame { * @param timeout The timeout to wait for. */ waitForTimeout(timeout: number): Promise; -} - -/** - * JSHandle represents an in-page JavaScript object. - */ -export interface JSHandle { - /** - * Returns either `null` or the object handle itself, if the object handle is - * an instance of `ElementHandle`. - * @returns The ElementHandle if available. - */ - asElement(): Promise; - - /** - * Stops referencing the element handle. - */ - dispose(): Promise; /** - * Evaluates the page function and returns its return value. - * This method passes this handle as the first argument to the page function. - * @param pageFunction The function to be evaluated. - * @param args The arguments to pass to the page function. - * @returns The return value of `pageFunction`. + * Returns {@link Locator} to the element with the corresponding role. + * + * @example + * ```js + * const locator = frame.getByRole('button', { name: 'Pizza, Please!' }); + * + * await locator.click(); + * ``` + * + * @param role The role of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding role. */ - evaluate(pageFunction: PageFunction, arg?: Arg): Promise; + getByRole( + role: + | "alert" + | "alertdialog" + | "application" + | "article" + | "banner" + | "blockquote" + | "button" + | "caption" + | "cell" + | "checkbox" + | "code" + | "columnheader" + | "combobox" + | "complementary" + | "contentinfo" + | "definition" + | "dialog" + | "directory" + | "document" + | "emphasis" + | "feed" + | "figure" + | "form" + | "generic" + | "grid" + | "gridcell" + | "group" + | "heading" + | "img" + | "insertion" + | "link" + | "list" + | "listbox" + | "listitem" + | "log" + | "main" + | "marquee" + | "math" + | "menu" + | "menubar" + | "menuitem" + | "menuitemcheckbox" + | "menuitemradio" + | "meter" + | "navigation" + | "none" + | "note" + | "option" + | "presentation" + | "progressbar" + | "radio" + | "radiogroup" + | "region" + | "row" + | "rowgroup" + | "rowheader" + | "scrollbar" + | "search" + | "searchbox" + | "separator" + | "slider" + | "spinbutton" + | "status" + | "strong" + | "subscript" + | "superscript" + | "switch" + | "tab" + | "table" + | "tablist" + | "tabpanel" + | "term" + | "textbox" + | "time" + | "timer" + | "toolbar" + | "tooltip" + | "tree" + | "treegrid" + | "treeitem", + options?: { + /** + * Whether the accessible `options.name` should be checked exactly for equality. + * + * @defaultValue false + */ + exact?: boolean; - /** - * Evaluates the page function and returns a `JSHandle`. - * This method passes this handle as the first argument to the page function. - * Unlike `evaluate`, `evaluateHandle` returns the value as a `JSHandle` - * @param pageFunction The function to be evaluated. - * @param args The arguments to pass to the page function. - * @returns A JSHandle of the return value of `pageFunction`. - */ - evaluateHandle(pageFunction: PageFunction, arg?: Arg): Promise>; + /** + * Whether to include elements that are normally excluded from the accessibility tree. + * + * @defaultValue false + */ + includeHidden?: boolean; - /** - * Fetches a map with own property names of of the `JSHandle` with their values as - * `JSHandle` instances. - * @returns A map with property names as keys and `JSHandle` instances for the property values. - */ - getProperties(): Promise>; + /** + * A number attribute that is traditionally used for headings h1-h6. + */ + level?: number; - /** - * Fetches a JSON representation of the object. - * @returns A JSON representation of the object. - */ - jsonValue(): Promise; -} + /** + * An accessible name for the element, such as a text in a button or a label for an input. + */ + name?: string | RegExp; -/** - * Keyboard provides an API for managing a virtual keyboard. - */ -export interface Keyboard { - /** - * Sends a key down message to a session target. - * A superset of the key values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values). - * @param key Name of key to press, such as `ArrowLeft`. - */ - down(key: string): Promise; + /** + * A boolean attribute that can be used to indicate if a checkbox is checked or not. + */ + checked?: boolean; - /** - * Dispatches an `input` event with the given `text`. - * This method does not emit `keyDown`, `keyUp` or `keyPress` events. - * @param text Event text. - */ - insertText(text: string): Promise; + /** + * A boolean attribute that can be used to indicate if an element is disabled or not. + */ + disabled?: boolean; - /** - * Sends a key press message to a session target. - * A press message consists of successive key down and up messages. - * @param key Sequence of keys to press. - * @param options Specifies the typing options. - */ - press(key: string, options?: { delay?: number }): Promise; + /** + * A boolean attribute that can be used to indicate if an element is expanded or not. + */ + expanded?: boolean; - /** - * Type sends a `press` message to a session target for each character in text. - * It sends an insertText message if a character is not among - * valid characters in the keyboard's layout. - * Modifier keys `Shift`, `Control`, `Alt`, `Meta` are _not_ respected. - * @param text A text to type into a focused element. - * @param options Specifies the typing options. - */ - type(text: string, options?: { delay?: number }): Promise; + /** + * A boolean attribute that can be used to indicate if an element is pressed or not. + */ + pressed?: boolean; - /** - * Sends a key up message to a session target. - * A superset of the key values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values). - * @param key Name of key to release, such as `ArrowLeft`. - */ - up(key: string): Promise; -} + /** + * A boolean attribute that can be used to indicate if an element is selected or not. + */ + selected?: boolean; + }, + ): Locator; -/** - * The Locator API makes it easier to work with dynamically changing elements. - * Some of the benefits of using it over existing ways to locate an element - * (e.g. Page.$()) include: - * - * - Helps with writing robust tests by finding an element even if the - * underlying frame navigates. - * - Makes it easier to work with dynamic web pages and SPAs built with Svelte, - * React, Vue, etc. - */ -export interface Locator { /** - * Returns an array of locators matching the selector. - * - * **Usage** + * Returns {@link Locator} to the element with the corresponding alt text. * + * @example * ```js - * // Select all options - * for (const option of await page.locator('option').all()) - * await option.click(); + * const locator = frame.getByAltText('pizza'); + * + * await locator.click(); * ``` * - * @returns Array of locators + * @param altText The alt text of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding alt text. */ - all(): Promise; - - /** - * Clears text boxes and input fields of any existing values. - * - * **Usage** - * + getByAltText( + altText: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding label text. + * + * @example + * ```js + * const locator = frame.getByLabel('Password'); + * + * await locator.fill('my-password'); + * ``` + * + * @param label The label text of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding label text. + */ + getByLabel( + label: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; + + /** + * Allows locating elements by their text content. Returns {@link Locator}. + * + * Consider the following DOM structure: + * + * ```html + *
Hello world
+ *
Hello
+ * ``` + * + * You can locate by text substring, exact string, or a regular expression: + * + * @example + * ```js + * // Matches + * frame.getByText('world'); + * + * // Matches first
+ * frame.getByText('Hello world'); + * + * // Matches second
+ * frame.getByText('Hello', { exact: true }); + * + * // Matches both
s + * frame.getByText(/Hello/); + * + * // Matches second
+ * frame.getByText(/^hello$/i); + * ``` + * + * Matching by text always normalizes whitespace, even with exact match. For + * example, it turns multiple spaces into one, turns line breaks into spaces + * and ignores leading and trailing whitespace. + * + * Input elements of the type `button` and `submit` are matched by their + * `value` instead of the text content. For example, locating by text + * `"Log in"` matches ``. + * + * @param text Text to locate the element by. + * @param options Options to use. + * @returns The locator to the element with the corresponding text content. + */ + getByText( + text: string | RegExp, + options?: { + /** + * Whether to find an exact match: case-sensitive and whole-string. + * Default to false. Ignored when locating by a regular expression. + * Note that exact match still trims whitespace. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding test ID. + * Note that this method only supports the `data-testid` attribute. + * + * @example + * HTML: + * ```html + * + * ``` + * + * JavaScript: + * ```js + * const locator = frame.getByTestId('submit-button'); + * + * await locator.click(); + * ``` + * + * @param testId The test ID of the element. + * @returns The locator to the element with the corresponding test ID. + */ + getByTestId(testId: string | RegExp): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding placeholder text. + * + * @example + * ```js + * const locator = frame.getByPlaceholder('name@example.com'); + * + * await locator.fill('my.name@example.com'); + * ``` + * + * @param placeholder The placeholder text of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding placeholder text. + */ + getByPlaceholder( + placeholder: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding title text. + * + * @example + * ```js + * const locator = frame.getByTitle('Information box'); + * + * await locator.click(); + * ``` + * + * @param title The title text of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding title text. + */ + getByTitle( + title: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; +} + +/** + * FrameLocator makes it easier to locate elements within an `iframe` on the + * page. `FrameLocator` are created by calling `page.locator(selector).contentFrame()`. + * It works in the same way as `Locator` instances. + */ +export interface FrameLocator { + /** + * The method finds all elements matching the selector and creates a new + * locator that matches all of them. This method can be used to further + * refine the locator by chaining additional selectors. + * + * @example + * ```js + * const frame = page.frameLocator('iframe'); + * const rows = frame.locator('table tr'); + * const cell = rows.locator('.selected'); + * + * // Use with options to filter by text + * const submitButton = frame.locator('button', { hasText: 'Submit' }); + * ``` + * + * @param selector A selector to use when resolving DOM element. + * @param options Options to use for filtering. + * @returns The new locator. + */ + locator(selector: string, options?: LocatorOptions): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding role. + * + * @example + * ```js + * const locator = frameLocator.getByRole('button', { name: 'Pizza, Please!' }); + * + * await locator.click(); + * ``` + * + * @param role The role of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding role. + */ + getByRole( + role: + | "alert" + | "alertdialog" + | "application" + | "article" + | "banner" + | "blockquote" + | "button" + | "caption" + | "cell" + | "checkbox" + | "code" + | "columnheader" + | "combobox" + | "complementary" + | "contentinfo" + | "definition" + | "dialog" + | "directory" + | "document" + | "emphasis" + | "feed" + | "figure" + | "form" + | "generic" + | "grid" + | "gridcell" + | "group" + | "heading" + | "img" + | "insertion" + | "link" + | "list" + | "listbox" + | "listitem" + | "log" + | "main" + | "marquee" + | "math" + | "menu" + | "menubar" + | "menuitem" + | "menuitemcheckbox" + | "menuitemradio" + | "meter" + | "navigation" + | "none" + | "note" + | "option" + | "presentation" + | "progressbar" + | "radio" + | "radiogroup" + | "region" + | "row" + | "rowgroup" + | "rowheader" + | "scrollbar" + | "search" + | "searchbox" + | "separator" + | "slider" + | "spinbutton" + | "status" + | "strong" + | "subscript" + | "superscript" + | "switch" + | "tab" + | "table" + | "tablist" + | "tabpanel" + | "term" + | "textbox" + | "time" + | "timer" + | "toolbar" + | "tooltip" + | "tree" + | "treegrid" + | "treeitem", + options?: { + /** + * Whether the accessible `options.name` should be checked exactly for equality. + * + * @defaultValue false + */ + exact?: boolean; + + /** + * Whether to include elements that are normally excluded from the accessibility tree. + * + * @defaultValue false + */ + includeHidden?: boolean; + + /** + * A number attribute that is traditionally used for headings h1-h6. + */ + level?: number; + + /** + * An accessible name for the element, such as a text in a button or a label for an input. + */ + name?: string | RegExp; + + /** + * A boolean attribute that can be used to indicate if a checkbox is checked or not. + */ + checked?: boolean; + + /** + * A boolean attribute that can be used to indicate if an element is disabled or not. + */ + disabled?: boolean; + + /** + * A boolean attribute that can be used to indicate if an element is expanded or not. + */ + expanded?: boolean; + + /** + * A boolean attribute that can be used to indicate if an element is pressed or not. + */ + pressed?: boolean; + + /** + * A boolean attribute that can be used to indicate if an element is selected or not. + */ + selected?: boolean; + }, + ): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding alt text. + * + * @example + * ```js + * const locator = frameLocator.getByAltText('pizza'); + * + * await locator.click(); + * ``` + * + * @param altText The alt text of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding alt text. + */ + getByAltText( + altText: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding label text. + * + * @example + * ```js + * const locator = frameLocator.getByLabel('Password'); + * + * await locator.fill('my-password'); + * ``` + * + * @param label The label text of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding label text. + */ + getByLabel( + label: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; + + /** + * Allows locating elements by their text content. Returns {@link Locator}. + * + * Consider the following DOM structure: + * + * ```html + *
Hello world
+ *
Hello
+ * ``` + * + * You can locate by text substring, exact string, or a regular expression: + * + * @example + * ```js + * // Matches + * frameLocator.getByText('world'); + * + * // Matches first
+ * frameLocator.getByText('Hello world'); + * + * // Matches second
+ * frameLocator.getByText('Hello', { exact: true }); + * + * // Matches both
s + * frameLocator.getByText(/Hello/); + * + * // Matches second
+ * frameLocator.getByText(/^hello$/i); + * ``` + * + * Matching by text always normalizes whitespace, even with exact match. For + * example, it turns multiple spaces into one, turns line breaks into spaces + * and ignores leading and trailing whitespace. + * + * Input elements of the type `button` and `submit` are matched by their + * `value` instead of the text content. For example, locating by text + * `"Log in"` matches ``. + * + * @param text Text to locate the element by. + * @param options Options to use. + * @returns The locator to the element with the corresponding text content. + */ + getByText( + text: string | RegExp, + options?: { + /** + * Whether to find an exact match: case-sensitive and whole-string. + * Default to false. Ignored when locating by a regular expression. + * Note that exact match still trims whitespace. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding test ID. + * Note that this method only supports the `data-testid` attribute. + * + * @example + * HTML: + * ```html + * + * ``` + * + * JavaScript: + * ```js + * const locator = frameLocator.getByTestId('submit-button'); + * + * await locator.click(); + * ``` + * + * @param testId The test ID of the element. + * @returns The locator to the element with the corresponding test ID. + */ + getByTestId(testId: string | RegExp): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding placeholder text. + * + * @example + * ```js + * const locator = frameLocator.getByPlaceholder('name@example.com'); + * + * await locator.fill('my.name@example.com'); + * ``` + * + * @param placeholder The placeholder text of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding placeholder text. + */ + getByPlaceholder( + placeholder: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; + + /** + * Returns {@link Locator} to the element with the corresponding title text. + * + * @example + * ```js + * const locator = frameLocator.getByTitle('Information box'); + * + * await locator.click(); + * ``` + * + * @param title The title text of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding title text. + */ + getByTitle( + title: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; +} + +/** + * JSHandle represents an in-page JavaScript object. + */ +export interface JSHandle { + /** + * Returns either `null` or the object handle itself, if the object handle is + * an instance of `ElementHandle`. + * @returns The ElementHandle if available. + */ + asElement(): Promise; + + /** + * Stops referencing the element handle. + */ + dispose(): Promise; + + /** + * Evaluates the page function and returns its return value. + * This method passes this handle as the first argument to the page function. + * @param pageFunction The function to be evaluated. + * @param args The arguments to pass to the page function. + * @returns The return value of `pageFunction`. + */ + evaluate(pageFunction: PageFunction, arg?: Arg): Promise; + + /** + * Evaluates the page function and returns a `JSHandle`. + * This method passes this handle as the first argument to the page function. + * Unlike `evaluate`, `evaluateHandle` returns the value as a `JSHandle` + * @param pageFunction The function to be evaluated. + * @param args The arguments to pass to the page function. + * @returns A JSHandle of the return value of `pageFunction`. + */ + evaluateHandle(pageFunction: PageFunction, arg?: Arg): Promise>; + + /** + * Fetches a map with own property names of of the `JSHandle` with their values as + * `JSHandle` instances. + * @returns A map with property names as keys and `JSHandle` instances for the property values. + */ + getProperties(): Promise>; + + /** + * Fetches a JSON representation of the object. + * @returns A JSON representation of the object. + */ + jsonValue(): Promise; +} + +/** + * Keyboard provides an API for managing a virtual keyboard. + */ +export interface Keyboard { + /** + * Sends a key down message to a session target. + * A superset of the key values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values). + * @param key Name of key to press, such as `ArrowLeft`. + */ + down(key: string): Promise; + + /** + * Dispatches an `input` event with the given `text`. + * This method does not emit `keyDown`, `keyUp` or `keyPress` events. + * @param text Event text. + */ + insertText(text: string): Promise; + + /** + * Sends a key press message to a session target. + * A press message consists of successive key down and up messages. + * @param key Sequence of keys to press. + * @param options Specifies the typing options. + */ + press(key: string, options?: { delay?: number }): Promise; + + /** + * Type sends a `press` message to a session target for each character in text. + * It sends an insertText message if a character is not among + * valid characters in the keyboard's layout. + * Modifier keys `Shift`, `Control`, `Alt`, `Meta` are _not_ respected. + * @param text A text to type into a focused element. + * @param options Specifies the typing options. + */ + type(text: string, options?: { delay?: number }): Promise; + + /** + * Sends a key up message to a session target. + * A superset of the key values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values). + * @param key Name of key to release, such as `ArrowLeft`. + */ + up(key: string): Promise; +} + +export interface LocatorOptions { + /** + * Matches only elements that contain the specified text. String or regular expression. + */ + hasText?: string | RegExp; + + /** + * Matches only elements that do not contain the specified text. String or regular expression. + */ + hasNotText?: string | RegExp; +} + +export interface LocatorFilterOptions { + /** + * Matches only elements that contain the specified text. String or regular expression. + */ + hasText?: string | RegExp; + + /** + * Matches only elements that do not contain the specified text. String or regular expression. + */ + hasNotText?: string | RegExp; +} + +/** + * The Locator API makes it easier to work with dynamically changing elements. + * Some of the benefits of using it over existing ways to locate an element + * (e.g. Page.$()) include: + * + * - Helps with writing robust tests by finding an element even if the + * underlying frame navigates. + * - Makes it easier to work with dynamic web pages and SPAs built with Svelte, + * React, Vue, etc. + */ +export interface Locator { + /** + * Returns an array of locators matching the selector. + * + * **Usage** + * + * ```js + * // Select all options + * for (const option of await page.locator('option').all()) + * await option.click(); + * ``` + * + * @returns Array of locators + */ + all(): Promise; + + /** + * Returns the bounding box of the element that this locator points to. + * + * **Usage** + * + * ```js + * const locator = page.locator('#my-element'); + * const boundingBox = await locator.boundingBox(); + * ``` + * + * @param options Options to use. + * @returns The bounding box of the element, or null if the element is not visible. + */ + boundingBox(options?: TimeoutOptions): Promise; + + /** + * Clears text boxes and input fields of any existing values. + * + * **Usage** + * * ```js * // Clears the input field matching the selector. * page.locator('input[name="login"]').clear(); @@ -2094,248 +2829,628 @@ export interface Locator { * * @param options Options to use. */ - clear(options?: ElementHandleOptions): Promise; + clear(options?: ElementHandleOptions): Promise; + + /** + * Mouse click on the chosen element. + * @param options Options to use. + * @returns Promise which resolves when the element is successfully clicked. + */ + click(options?: MouseMoveOptions & MouseMultiClickOptions): Promise; + + /** + * Returns a `FrameLocator` that can be used to locate elements within an + * `iframe`. + * @returns A `FrameLocator`. + */ + contentFrame(): FrameLocator; + + /** + * Returns the number of elements matching the selector. + * + * **Usage** + * + * ```js + * const count = await page.locator('input').count(); + * ``` + * + * @returns Promise which resolves with the number of elements matching the selector. + */ + count(): Promise; + + /** + * Mouse double click on the chosen element. + * @param options Options to use. + */ + dblclick(options?: MouseMoveOptions & MouseMultiClickOptions): Promise; + + /** + * Use this method to select an `input type="checkbox"`. + * @param options Options to use. + */ + check(options?: ElementClickOptions): Promise; + + /** + * Use this method to unselect an `input type="checkbox"`. + * @param options Options to use. + */ + uncheck(options?: ElementClickOptions): Promise; + + /** + * Checks to see if the `input type="checkbox"` is selected or not. + * @param options Options to use. + * @returns `true` if the element is checked, `false` otherwise. + */ + isChecked(options?: TimeoutOptions): Promise; + + /** + * Checks if the element is editable. + * @param options Options to use. + * @returns `true` if the element is editable, `false` otherwise. + */ + isEditable(options?: TimeoutOptions): Promise; + + /** + * Checks if the element is `enabled`. + * @param options Options to use. + * @returns `true` if the element is enabled, `false` otherwise. + */ + isEnabled(options?: TimeoutOptions): Promise; + + /** + * Checks if the element is `disabled`. + * @param options Options to use. + * @returns `true` if the element is disabled, `false` otherwise. + */ + isDisabled(options?: TimeoutOptions): Promise; + + /** + * Checks if the element is `visible`. + * @returns `true` if the element is visible, `false` otherwise. + */ + isVisible(): Promise; + + /** + * Checks if the element is `hidden`. + * @returns `true` if the element is hidden, `false` otherwise. + */ + isHidden(): Promise; + + /** + * Fill an `input`, `textarea` or `contenteditable` element with the provided value. + * @param value Value to fill for the `input` or `textarea` element. + * @param options Options to use. + */ + fill(value: string, options?: ElementHandleOptions): Promise; + + /** + * Returns locator to the first matching element. + * + * **Usage** + * + * ```js + * const firstRow = await page.locator('tr').first(); + * ``` + * + * @returns Locator. + */ + first(): Locator; + + /** + * Focuses the element using locator's selector. + * @param options Options to use. + */ + focus(options?: TimeoutOptions): Promise; + + /** + * Returns the element attribute value for the given attribute name. + * @param name Attribute name to retrieve value for. + * @param options Options to use. + * @returns Attribute value. + */ + getAttribute(name: string, options?: TimeoutOptions): Promise; + + /** + * Returns the `element.innerHTML`. + * @param options Options to use. + * @returns Element's innerHTML. + */ + innerHTML(options?: TimeoutOptions): Promise; + + /** + * Returns the `element.innerText`. + * @param options Options to use. + * @returns Element's innerText. + */ + innerText(options?: TimeoutOptions): Promise; + + /** + * Returns the `element.textContent`. + * @param options Options to use. + * @returns Element's textContent. + */ + textContent(options?: TimeoutOptions): Promise; + + /** + * Returns `input.value` for the selected `input`, `textarea` or `select` element. + * @param options Options to use. + * @returns The input value of the element. + */ + inputValue(options?: TimeoutOptions): Promise; + + /** + * Returns locator to the last matching element. + * + * **Usage** + * + * ```js + * const lastRow = await page.locator('tr').last(); + * ``` + * + * @returns Locator. + */ + last(): Locator; /** - * Mouse click on the chosen element. - * @param options Options to use. - * @returns Promise which resolves when the element is successfully clicked. + * The method finds all elements matching the selector and creates a new + * locator that matches all of them. This method can be used to further + * refine the locator by chaining additional selectors. + * + * @example + * ```js + * const rows = page.locator('table tr'); + * const cell = rows.locator('.selected'); + * + * // Use with options to filter + * const orangeButton = fruitsSection.locator('button', { hasText: 'Add to Cart' }); + * ``` + * + * @param selector A selector to use when resolving DOM element. + * @param options Options to use for filtering. + * @returns The new locator. */ - click(options?: MouseMoveOptions & MouseMultiClickOptions): Promise; + locator(selector: string, options?: LocatorOptions): Locator; /** - * Returns the number of elements matching the selector. + * Returns locator to the n-th matching element. It's zero based, `nth(0)` selects the first element. * * **Usage** * * ```js - * const count = await page.locator('input').count(); + * const secondRow = await page.locator('tr').nth(1); * ``` * - * @returns Promise which resolves with the number of elements matching the selector. + * @param index + * @returns Locator */ - count(): Promise; + nth(index: number): Locator; /** - * Mouse double click on the chosen element. + * Select one or more options which match the values. If the select has the multiple attribute, all matching options are selected, + * otherwise only the first option matching one of the passed options is selected. + * + * @example + * ```js + * // Single selection matching the value or label + * locator.selectOption('blue'); + * + * // single selection matching the label + * locator.selectOption({ label: 'Blue' }); + * + * // multiple selection + * locator.selectOption(['red', 'green', 'blue']); + * ``` + * + * @param values Values of options to select. * @param options Options to use. + * @returns List of selected options. */ - dblclick(options?: MouseMoveOptions & MouseMultiClickOptions): Promise; + selectOption( + values: string | string[] | { value?: string; label?: string; index?: number }, + options?: ElementHandleOptions, + ): Promise; /** - * Use this method to select an `input type="checkbox"`. - * @param options Options to use. + * Checks or unchecks the input checkbox element. + * @param checked Whether to check or uncheck the element. + * @param options Options to customize the check action. + * @returns A promise that resolves when the element is checked or unchecked. */ - check(options?: ElementClickOptions): Promise; + setChecked(checked: boolean, options?: FrameCheckOptions): Promise; /** - * Use this method to unselect an `input type="checkbox"`. - * @param options Options to use. + * Press a single key on the keyboard or a combination of keys. + * A superset of the key values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values). + * @param key Name of the key to press or a character to generate, such as `ArrowLeft` or `a`. + * @param options Keyboard press options. */ - uncheck(options?: ElementClickOptions): Promise; + press(key: string, options?: KeyboardPressOptions): Promise; /** - * Checks to see if the `input type="checkbox"` is selected or not. - * @param options Options to use. - * @returns `true` if the element is checked, `false` otherwise. + * Type a text into the input field. + * @param text Text to type into the input field. + * @param options Typing options. */ - isChecked(options?: TimeoutOptions): Promise; + type(text: string, options?: KeyboardPressOptions): Promise; /** - * Checks if the element is editable. + * Hover over the element. * @param options Options to use. - * @returns `true` if the element is editable, `false` otherwise. */ - isEditable(options?: TimeoutOptions): Promise; + hover(options?: MouseMoveOptions): Promise; /** - * Checks if the element is `enabled`. + * Tap on the chosen element. * @param options Options to use. - * @returns `true` if the element is enabled, `false` otherwise. */ - isEnabled(options?: TimeoutOptions): Promise; + tap(options?: MouseMoveOptions): Promise; /** - * Checks if the element is `disabled`. + * Dispatches HTML DOM event types e.g. `click`. + * @param type DOM event type. + * @param eventInit Event-specific properties. * @param options Options to use. - * @returns `true` if the element is disabled, `false` otherwise. - */ - isDisabled(options?: TimeoutOptions): Promise; - - /** - * Checks if the element is `visible`. - * @returns `true` if the element is visible, `false` otherwise. - */ - isVisible(): Promise; - - /** - * Checks if the element is `hidden`. - * @returns `true` if the element is hidden, `false` otherwise. */ - isHidden(): Promise; + dispatchEvent(type: string, eventInit?: EvaluationArgument, options?: TimeoutOptions): Promise; /** - * Fill an `input`, `textarea` or `contenteditable` element with the provided value. - * @param value Value to fill for the `input` or `textarea` element. - * @param options Options to use. + * Wait for the element to be in a particular state e.g. `visible`. + * @param options Wait options. */ - fill(value: string, options?: ElementHandleOptions): Promise; + waitFor(options?: { state?: ElementState } & TimeoutOptions): Promise; /** - * Returns locator to the first matching element. - * - * **Usage** + * Returns a new Locator that matches only elements with the given options. * + * @example * ```js - * const firstRow = await page.locator('tr').first(); + * // Filter list items that contain "Product 2" text + * const product2Item = page + * .locator('li') + * .filter({ hasText: 'Product 2' }) + * .first(); + * + * // Filter list items that do NOT contain "Product 2" using regex + * const product1Item = page + * .locator('li') + * .filter({ hasNotText: /Product 2/ }) + * .first(); * ``` * - * @returns Locator. + * @param options Filter options. + * @returns A new filtered Locator that can be chained with other methods. */ - first(): Locator; + filter(options: LocatorFilterOptions): Locator; /** - * Focuses the element using locator's selector. + * Returns {@link Locator} to the element with the corresponding role. + * + * @example + * ```js + * const locator = locator.getByRole('button', { name: 'Pizza, Please!' }); + * + * await locator.click(); + * ``` + * + * @param role The role of the element. * @param options Options to use. + * @returns The locator to the element with the corresponding role. */ - focus(options?: TimeoutOptions): Promise; + getByRole( + role: + | "alert" + | "alertdialog" + | "application" + | "article" + | "banner" + | "blockquote" + | "button" + | "caption" + | "cell" + | "checkbox" + | "code" + | "columnheader" + | "combobox" + | "complementary" + | "contentinfo" + | "definition" + | "dialog" + | "directory" + | "document" + | "emphasis" + | "feed" + | "figure" + | "form" + | "generic" + | "grid" + | "gridcell" + | "group" + | "heading" + | "img" + | "insertion" + | "link" + | "list" + | "listbox" + | "listitem" + | "log" + | "main" + | "marquee" + | "math" + | "menu" + | "menubar" + | "menuitem" + | "menuitemcheckbox" + | "menuitemradio" + | "meter" + | "navigation" + | "none" + | "note" + | "option" + | "presentation" + | "progressbar" + | "radio" + | "radiogroup" + | "region" + | "row" + | "rowgroup" + | "rowheader" + | "scrollbar" + | "search" + | "searchbox" + | "separator" + | "slider" + | "spinbutton" + | "status" + | "strong" + | "subscript" + | "superscript" + | "switch" + | "tab" + | "table" + | "tablist" + | "tabpanel" + | "term" + | "textbox" + | "time" + | "timer" + | "toolbar" + | "tooltip" + | "tree" + | "treegrid" + | "treeitem", + options?: { + /** + * Whether the accessible `options.name` should be checked exactly for equality. + * + * @defaultValue false + */ + exact?: boolean; - /** - * Returns the element attribute value for the given attribute name. - * @param name Attribute name to retrieve value for. - * @param options Options to use. - * @returns Attribute value. - */ - getAttribute(name: string, options?: TimeoutOptions): Promise; + /** + * Whether to include elements that are normally excluded from the accessibility tree. + * + * @defaultValue false + */ + includeHidden?: boolean; - /** - * Returns the `element.innerHTML`. - * @param options Options to use. - * @returns Element's innerHTML. - */ - innerHTML(options?: TimeoutOptions): Promise; + /** + * A number attribute that is traditionally used for headings h1-h6. + */ + level?: number; + + /** + * An accessible name for the element, such as a text in a button or a label for an input. + */ + name?: string | RegExp; + + /** + * A boolean attribute that can be used to indicate if a checkbox is checked or not. + */ + checked?: boolean; + + /** + * A boolean attribute that can be used to indicate if an element is disabled or not. + */ + disabled?: boolean; + + /** + * A boolean attribute that can be used to indicate if an element is expanded or not. + */ + expanded?: boolean; - /** - * Returns the `element.innerText`. - * @param options Options to use. - * @returns Element's innerText. - */ - innerText(options?: TimeoutOptions): Promise; + /** + * A boolean attribute that can be used to indicate if an element is pressed or not. + */ + pressed?: boolean; - /** - * Returns the `element.textContent`. - * @param options Options to use. - * @returns Element's textContent. - */ - textContent(options?: TimeoutOptions): Promise; + /** + * A boolean attribute that can be used to indicate if an element is selected or not. + */ + selected?: boolean; + }, + ): Locator; /** - * Returns `input.value` for the selected `input`, `textarea` or `select` element. + * Returns {@link Locator} to the element with the corresponding alt text. + * + * @example + * ```js + * const locator = locator.getByAltText('pizza'); + * + * await locator.click(); + * ``` + * + * @param altText The alt text of the element. * @param options Options to use. - * @returns The input value of the element. + * @returns The locator to the element with the corresponding alt text. */ - inputValue(options?: TimeoutOptions): Promise; + getByAltText( + altText: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; /** - * Returns locator to the last matching element. - * - * **Usage** + * Returns {@link Locator} to the element with the corresponding label text. * + * @example * ```js - * const lastRow = await page.locator('tr').last(); + * const locator = locator.getByLabel('Password'); + * + * await locator.fill('my-password'); * ``` * - * @returns Locator. + * @param label The label text of the element. + * @param options Options to use. + * @returns The locator to the element with the corresponding label text. */ - last(): Locator; + getByLabel( + label: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; /** - * Returns locator to the n-th matching element. It's zero based, `nth(0)` selects the first element. + * Allows locating elements by their text content. Returns {@link Locator}. * - * **Usage** + * Consider the following DOM structure: * - * ```js - * const secondRow = await page.locator('tr').nth(1); + * ```html + *
Hello world
+ *
Hello
* ``` * - * @param index - * @returns Locator - */ - nth(index: number): Locator; - - /** - * Select one or more options which match the values. If the select has the multiple attribute, all matching options are selected, - * otherwise only the first option matching one of the passed options is selected. + * You can locate by text substring, exact string, or a regular expression: * * @example * ```js - * // Single selection matching the value or label - * locator.selectOption('blue'); + * // Matches + * locator.getByText('world'); * - * // single selection matching the label - * locator.selectOption({ label: 'Blue' }); + * // Matches first
+ * locator.getByText('Hello world'); * - * // multiple selection - * locator.selectOption(['red', 'green', 'blue']); + * // Matches second
+ * locator.getByText('Hello', { exact: true }); + * + * // Matches both
s + * locator.getByText(/Hello/); + * + * // Matches second
+ * locator.getByText(/^hello$/i); * ``` * - * @param values Values of options to select. + * Matching by text always normalizes whitespace, even with exact match. For + * example, it turns multiple spaces into one, turns line breaks into spaces + * and ignores leading and trailing whitespace. + * + * Input elements of the type `button` and `submit` are matched by their + * `value` instead of the text content. For example, locating by text + * `"Log in"` matches ``. + * + * @param text Text to locate the element by. * @param options Options to use. - * @returns List of selected options. - */ - selectOption( - values: string | string[] | { value?: string; label?: string; index?: number }, - options?: ElementHandleOptions, - ): Promise; - - /** - * Checks or unchecks the input checkbox element. - * @param checked Whether to check or uncheck the element. - * @param options Options to customize the check action. - * @returns A promise that resolves when the element is checked or unchecked. - */ - setChecked(checked: boolean, options?: FrameCheckOptions): Promise; - - /** - * Press a single key on the keyboard or a combination of keys. - * A superset of the key values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values). - * @param key Name of the key to press or a character to generate, such as `ArrowLeft` or `a`. - * @param options Keyboard press options. - */ - press(key: string, options?: KeyboardPressOptions): Promise; - - /** - * Type a text into the input field. - * @param text Text to type into the input field. - * @param options Typing options. + * @returns The locator to the element with the corresponding text content. */ - type(text: string, options?: KeyboardPressOptions): Promise; + getByText( + text: string | RegExp, + options?: { + /** + * Whether to find an exact match: case-sensitive and whole-string. + * Default to false. Ignored when locating by a regular expression. + * Note that exact match still trims whitespace. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; /** - * Hover over the element. - * @param options Options to use. + * Returns {@link Locator} to the element with the corresponding test ID. + * Note that this method only supports the `data-testid` attribute. + * + * @example + * HTML: + * ```html + * + * ``` + * + * JavaScript: + * ```js + * const locator = locator.getByTestId('submit-button'); + * + * await locator.click(); + * ``` + * + * @param testId The test ID of the element. + * @returns The locator to the element with the corresponding test ID. */ - hover(options?: MouseMoveOptions): Promise; + getByTestId(testId: string | RegExp): Locator; /** - * Tap on the chosen element. + * Returns {@link Locator} to the element with the corresponding placeholder text. + * + * @example + * ```js + * const locator = locator.getByPlaceholder('name@example.com'); + * + * await locator.fill('my.name@example.com'); + * ``` + * + * @param placeholder The placeholder text of the element. * @param options Options to use. + * @returns The locator to the element with the corresponding placeholder text. */ - tap(options?: MouseMoveOptions): Promise; + getByPlaceholder( + placeholder: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; /** - * Dispatches HTML DOM event types e.g. `click`. - * @param type DOM event type. - * @param eventInit Event-specific properties. + * Returns {@link Locator} to the element with the corresponding title text. + * + * @example + * ```js + * const locator = locator.getByTitle('Information box'); + * + * await locator.click(); + * ``` + * + * @param title The title text of the element. * @param options Options to use. + * @returns The locator to the element with the corresponding title text. */ - dispatchEvent(type: string, eventInit?: EvaluationArgument, options?: TimeoutOptions): Promise; - - /** - * Wait for the element to be in a particular state e.g. `visible`. - * @param options Wait options. - */ - waitFor(options?: { state?: ElementState } & TimeoutOptions): Promise; + getByTitle( + title: string | RegExp, + options?: { + /** + * Whether the locator should be exact. + * + * @defaultValue false + */ + exact?: boolean; + }, + ): Locator; } /** @@ -3487,9 +4602,18 @@ export interface Page { * when the action takes place, which means locators can span over navigations * where the underlying dom changes. * + * @example + * ```js + * const textbox = page.locator('#text1'); + * + * // Create a locator with text filtering options + * const submitButton = page.locator('button', { hasText: 'Pizza, Please!' }); + * ``` + * * @param selector A selector to use when resolving DOM element. + * @param options Options to use for filtering. */ - locator(selector: string): Locator; + locator(selector: string, options?: LocatorOptions): Locator; /** * The page's main frame. Page is made up of frames in a hierarchical. At the @@ -4334,6 +5458,36 @@ export interface Page { }, ): Promise; + /** + * Waits for the page to match against the URL for a Response object + * + * @example + * ```js + * const responsePromise = page.waitForResponse('https://example.com/resource'); + * await page.goto('https://example.com/resource'); + * const response = await responsePromise; + * ``` + * + * @param response Request URL string or regex to match against Response object. + * @param options Options to use. + */ + waitForResponse( + response: string | RegExp, + options?: { + /** + * Maximum operation time in milliseconds. Defaults to `30` seconds. + * The default value can be changed via the + * browserContext.setDefaultNavigationTimeout(timeout), + * browserContext.setDefaultTimeout(timeout), + * page.setDefaultNavigationTimeout(timeout) or + * page.setDefaultTimeout(timeout) methods. + * + * Setting the value to `0` will disable the timeout. + */ + timeout?: number; + }, + ): Promise; + /** * **NOTE** Use web assertions that assert visibility or a locator-based * locator.waitFor([options]) instead. diff --git a/types/k6/package.json b/types/k6/package.json index 4ddb6f6f386682..06ebce9a9def0b 100644 --- a/types/k6/package.json +++ b/types/k6/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@types/k6", - "version": "1.2.9999", + "version": "1.3.9999", "type": "module", "projects": [ "https://grafana.com/docs/k6/latest/" @@ -54,6 +54,10 @@ { "name": "Joan López de la Franca Beltran", "githubUsername": "joanlopez" + }, + { + "name": "Agnès Toulet", + "githubUsername": "AgnesToulet" } ] } diff --git a/types/k6/test/browser.ts b/types/k6/test/browser.ts index 1592ae0fafa3b6..091ee35c7014f3 100644 --- a/types/k6/test/browser.ts +++ b/types/k6/test/browser.ts @@ -529,6 +529,16 @@ async function test() { page.locator(); // $ExpectType Locator page.locator(selector); + // $ExpectType Locator + page.locator(selector, { hasText: "Submit" }); + // $ExpectType Locator + page.locator(selector, { hasText: /Submit/ }); + // $ExpectType Locator + page.locator(selector, { hasNotText: "Cancel" }); + // $ExpectType Locator + page.locator(selector, { hasNotText: /Cancel/ }); + // $ExpectType Locator + page.locator(selector, { hasText: "Submit", hasNotText: "Cancel" }); // $ExpectType Frame page.mainFrame(); @@ -1021,6 +1031,15 @@ async function test() { // $ExpectType Promise page.waitForURL("https://example.com", { waitUntil: "domcontentloaded" }); + // @ts-expect-error + page.waitForResponse(); + // $ExpectType Promise + page.waitForResponse("https://example.com"); + // $ExpectType Promise + page.waitForResponse(/.*\/api\/pizza$/); + // $ExpectType Promise + page.waitForResponse("https://example.com", { timeout: 10000 }); + // @ts-expect-error page.waitForSelector(); // $ExpectType Promise @@ -1148,6 +1167,11 @@ async function test() { // const locator = page.locator(selector); + // $ExpectType Promise + locator.boundingBox(); + // $ExpectType Promise + locator.boundingBox({ timeout: 10000 }); + // $ExpectType Promise locator.clear(); // $ExpectType Promise @@ -1176,6 +1200,9 @@ async function test() { // $ExpectType Promise locator.click({ trial: true }); + // $ExpectType FrameLocator + locator.contentFrame(); + // $ExpectType Promise locator.dblclick(); // $ExpectType Promise @@ -1285,6 +1312,34 @@ async function test() { // $ExpectType Locator locator.last(); + // $ExpectType Locator + locator.locator("div"); + // $ExpectType Locator + locator.locator("div", { hasText: "Submit" }); + // $ExpectType Locator + locator.locator("div", { hasText: /Submit/ }); + // $ExpectType Locator + locator.locator("div", { hasNotText: "Cancel" }); + // $ExpectType Locator + locator.locator("div", { hasNotText: /Cancel/ }); + // $ExpectType Locator + locator.locator("div", { hasText: "Submit", hasNotText: "Cancel" }); + // @ts-expect-error + locator.locator(); + + // $ExpectType Locator + locator.filter({ hasText: "Submit" }); + // $ExpectType Locator + locator.filter({ hasText: /Submit/ }); + // $ExpectType Locator + locator.filter({ hasNotText: "Cancel" }); + // $ExpectType Locator + locator.filter({ hasNotText: /Cancel/ }); + // $ExpectType Locator + locator.filter({ hasText: "Submit", hasNotText: "Cancel" }); + // $ExpectType Locator + locator.filter({}); + // $ExpectType Locator locator.nth(0); // @ts-expect-error @@ -1401,6 +1456,94 @@ async function test() { // $ExpectType Promise locator.waitFor({ timeout: 10000 }); + // Locator getBy* methods tests + // $ExpectType Locator + locator.getByRole("button", { name: "Sign in" }); + // $ExpectType Locator + locator.getByRole("button", { name: /Sign in/i }); + // $ExpectType Locator + locator.getByRole("button", { exact: true }); + // $ExpectType Locator + locator.getByRole("checkbox", { checked: true }); + // $ExpectType Locator + locator.getByRole("checkbox", { disabled: true }); + // $ExpectType Locator + locator.getByRole("checkbox", { expanded: true }); + // $ExpectType Locator + locator.getByRole("checkbox", { includeHidden: true }); + // $ExpectType Locator + locator.getByRole("heading", { level: 1 }); + // $ExpectType Locator + locator.getByRole("checkbox", { pressed: true }); + // $ExpectType Locator + locator.getByRole("checkbox", { selected: true }); + // @ts-expect-error + locator.getByRole("button", { name: 123 }); + // @ts-expect-error + locator.getByRole("invalid-role"); + + // $ExpectType Locator + locator.getByAltText("pizza"); + // $ExpectType Locator + locator.getByAltText(/pizza/i); + // @ts-expect-error + locator.getByAltText(123); + // $ExpectType Locator + locator.getByAltText("pizza", { exact: true }); + // @ts-expect-error + locator.getByAltText("pizza", { exact: "true" }); + + // $ExpectType Locator + locator.getByLabel("Password"); + // $ExpectType Locator + locator.getByLabel(/Password/i); + // @ts-expect-error + locator.getByLabel(123); + // $ExpectType Locator + locator.getByLabel("Password", { exact: true }); + // @ts-expect-error + locator.getByLabel("Password", { exact: "true" }); + + // $ExpectType Locator + locator.getByText("Welcome"); + // $ExpectType Locator + locator.getByText(/Welcome/i); + // @ts-expect-error + locator.getByText(123); + // $ExpectType Locator + locator.getByText("Welcome", { exact: true }); + // @ts-expect-error + locator.getByText("Welcome", { exact: "true" }); + + // $ExpectType Locator + locator.getByTestId("submit-button"); + // $ExpectType Locator + locator.getByTestId(/submit-button/i); + // @ts-expect-error + locator.getByTestId(123); + + // $ExpectType Locator + locator.getByTitle("Information box"); + // $ExpectType Locator + locator.getByTitle(/Information box/i); + // @ts-expect-error + locator.getByTitle(123); + // $ExpectType Locator + locator.getByTitle("Information box", { exact: true }); + // @ts-expect-error + locator.getByTitle("Information box", { exact: "true" }); + + // $ExpectType Locator + locator.getByPlaceholder("name@example.com"); + // $ExpectType Locator + locator.getByPlaceholder(/name@example.com/i); + // @ts-expect-error + locator.getByPlaceholder(123); + // $ExpectType Locator + locator.getByPlaceholder("name@example.com", { exact: true }); + // @ts-expect-error + locator.getByPlaceholder("name@example.com", { exact: "true" }); + // // JSHandle // @@ -2214,6 +2357,16 @@ async function test() { frame.locator(); // $ExpectType Locator frame.locator("div"); + // $ExpectType Locator + frame.locator("div", { hasText: "Submit" }); + // $ExpectType Locator + frame.locator("div", { hasText: /Submit/ }); + // $ExpectType Locator + frame.locator("div", { hasNotText: "Cancel" }); + // $ExpectType Locator + frame.locator("div", { hasNotText: /Cancel/ }); + // $ExpectType Locator + frame.locator("div", { hasText: "Submit", hasNotText: "Cancel" }); // @ts-expect-error frame.innerHTML(); @@ -2393,11 +2546,207 @@ async function test() { frame.waitForSelector("div", { state: state as any }); } + // Frame getBy* methods tests + // $ExpectType Locator + frame.getByRole("button", { name: "Sign in" }); + // $ExpectType Locator + frame.getByRole("button", { name: /Sign in/i }); + // $ExpectType Locator + frame.getByRole("button", { exact: true }); + // $ExpectType Locator + frame.getByRole("checkbox", { checked: true }); + // $ExpectType Locator + frame.getByRole("checkbox", { disabled: true }); + // $ExpectType Locator + frame.getByRole("checkbox", { expanded: true }); + // $ExpectType Locator + frame.getByRole("checkbox", { includeHidden: true }); + // $ExpectType Locator + frame.getByRole("heading", { level: 1 }); + // $ExpectType Locator + frame.getByRole("checkbox", { pressed: true }); + // $ExpectType Locator + frame.getByRole("checkbox", { selected: true }); + // @ts-expect-error + frame.getByRole("button", { name: 123 }); + // @ts-expect-error + frame.getByRole("invalid-role"); + + // $ExpectType Locator + frame.getByAltText("pizza"); + // $ExpectType Locator + frame.getByAltText(/pizza/i); + // @ts-expect-error + frame.getByAltText(123); + // $ExpectType Locator + frame.getByAltText("pizza", { exact: true }); + // @ts-expect-error + frame.getByAltText("pizza", { exact: "true" }); + + // $ExpectType Locator + frame.getByLabel("Password"); + // $ExpectType Locator + frame.getByLabel(/Password/i); + // @ts-expect-error + frame.getByLabel(123); + // $ExpectType Locator + frame.getByLabel("Password", { exact: true }); + // @ts-expect-error + frame.getByLabel("Password", { exact: "true" }); + + // $ExpectType Locator + frame.getByText("Welcome"); + // $ExpectType Locator + frame.getByText(/Welcome/i); + // @ts-expect-error + frame.getByText(123); + // $ExpectType Locator + frame.getByText("Welcome", { exact: true }); + // @ts-expect-error + frame.getByText("Welcome", { exact: "true" }); + + // $ExpectType Locator + frame.getByTestId("submit-button"); + // $ExpectType Locator + frame.getByTestId(/submit-button/i); + // @ts-expect-error + frame.getByTestId(123); + + // $ExpectType Locator + frame.getByTitle("Information box"); + // $ExpectType Locator + frame.getByTitle(/Information box/i); + // @ts-expect-error + frame.getByTitle(123); + // $ExpectType Locator + frame.getByTitle("Information box", { exact: true }); + // @ts-expect-error + frame.getByTitle("Information box", { exact: "true" }); + + // $ExpectType Locator + frame.getByPlaceholder("name@example.com"); + // $ExpectType Locator + frame.getByPlaceholder(/name@example.com/i); + // @ts-expect-error + frame.getByPlaceholder(123); + // $ExpectType Locator + frame.getByPlaceholder("name@example.com", { exact: true }); + // @ts-expect-error + frame.getByPlaceholder("name@example.com", { exact: "true" }); + // @ts-expect-error frame.waitForTimeout(); // $ExpectType Promise frame.waitForTimeout(10000); + // + // FrameLocator + // + // $ExpectType FrameLocator + const frameLocator = page.locator(selector).contentFrame(); + // $ExpectType Locator + frameLocator.locator("div"); + // $ExpectType Locator + frameLocator.locator("div", { hasText: "Submit" }); + // $ExpectType Locator + frameLocator.locator("div", { hasText: /Submit/ }); + // $ExpectType Locator + frameLocator.locator("div", { hasNotText: "Cancel" }); + // $ExpectType Locator + frameLocator.locator("div", { hasNotText: /Cancel/ }); + // $ExpectType Locator + frameLocator.locator("div", { hasText: "Submit", hasNotText: "Cancel" }); + // @ts-expect-error + frameLocator.locator(); + + // FrameLocator getBy* methods tests + // $ExpectType Locator + frameLocator.getByRole("button", { name: "Sign in" }); + // $ExpectType Locator + frameLocator.getByRole("button", { name: /Sign in/i }); + // $ExpectType Locator + frameLocator.getByRole("button", { exact: true }); + // $ExpectType Locator + frameLocator.getByRole("checkbox", { checked: true }); + // $ExpectType Locator + frameLocator.getByRole("checkbox", { disabled: true }); + // $ExpectType Locator + frameLocator.getByRole("checkbox", { expanded: true }); + // $ExpectType Locator + frameLocator.getByRole("checkbox", { includeHidden: true }); + // $ExpectType Locator + frameLocator.getByRole("heading", { level: 1 }); + // $ExpectType Locator + frameLocator.getByRole("checkbox", { pressed: true }); + // $ExpectType Locator + frameLocator.getByRole("checkbox", { selected: true }); + // @ts-expect-error + frameLocator.getByRole("button", { name: 123 }); + // @ts-expect-error + frameLocator.getByRole("invalid-role"); + + // $ExpectType Locator + frameLocator.getByAltText("pizza"); + // $ExpectType Locator + frameLocator.getByAltText(/pizza/i); + // @ts-expect-error + frameLocator.getByAltText(123); + // $ExpectType Locator + frameLocator.getByAltText("pizza", { exact: true }); + // @ts-expect-error + frameLocator.getByAltText("pizza", { exact: "true" }); + + // $ExpectType Locator + frameLocator.getByLabel("Password"); + // $ExpectType Locator + frameLocator.getByLabel(/Password/i); + // @ts-expect-error + frameLocator.getByLabel(123); + // $ExpectType Locator + frameLocator.getByLabel("Password", { exact: true }); + // @ts-expect-error + frameLocator.getByLabel("Password", { exact: "true" }); + + // $ExpectType Locator + frameLocator.getByText("Welcome"); + // $ExpectType Locator + frameLocator.getByText(/Welcome/i); + // @ts-expect-error + frameLocator.getByText(123); + // $ExpectType Locator + frameLocator.getByText("Welcome", { exact: true }); + // @ts-expect-error + frameLocator.getByText("Welcome", { exact: "true" }); + + // $ExpectType Locator + frameLocator.getByTestId("submit-button"); + // $ExpectType Locator + frameLocator.getByTestId(/submit-button/i); + // @ts-expect-error + frameLocator.getByTestId(123); + + // $ExpectType Locator + frameLocator.getByTitle("Information box"); + // $ExpectType Locator + frameLocator.getByTitle(/Information box/i); + // @ts-expect-error + frameLocator.getByTitle(123); + // $ExpectType Locator + frameLocator.getByTitle("Information box", { exact: true }); + // @ts-expect-error + frameLocator.getByTitle("Information box", { exact: "true" }); + + // $ExpectType Locator + frameLocator.getByPlaceholder("name@example.com"); + // $ExpectType Locator + frameLocator.getByPlaceholder(/name@example.com/i); + // @ts-expect-error + frameLocator.getByPlaceholder(123); + // $ExpectType Locator + frameLocator.getByPlaceholder("name@example.com", { exact: true }); + // @ts-expect-error + frameLocator.getByPlaceholder("name@example.com", { exact: "true" }); + // // Touchscreen.tap //