feat: address api review feedback for 1.43 (#30066)
- Update docs for `trace: retain-on-first-failure`. - Update docs for `devtools` option. - Rename `Locator.enterFrame()` to `Locator.contentFrame()`. - Rename `FrameLocator.exitFrame()` to `FrameLocator.owner()`.
This commit is contained in:
parent
7a3c002944
commit
95d649b406
|
|
@ -74,57 +74,11 @@ await page.FrameLocator(".result-frame").First.getByRole(AriaRole.Button).ClickA
|
|||
|
||||
**Converting Locator to FrameLocator**
|
||||
|
||||
If you have a [Locator] object pointing to an `iframe` it can be converted to [FrameLocator] using [`method: Locator.enterFrame`].
|
||||
If you have a [Locator] object pointing to an `iframe` it can be converted to [FrameLocator] using [`method: Locator.contentFrame`].
|
||||
|
||||
**Converting FrameLocator to Locator**
|
||||
|
||||
If you have a [FrameLocator] object it can be converted to [Locator] pointing to the same `iframe` using [`method: FrameLocator.exitFrame`].
|
||||
|
||||
|
||||
## method: FrameLocator.exitFrame
|
||||
* since: v1.43
|
||||
- returns: <[Locator]>
|
||||
|
||||
Returns a [Locator] object pointing to the same `iframe` as this frame locator.
|
||||
|
||||
Useful when you have a [FrameLocator] object obtained somewhere, and later on would like to interact with the `iframe` element.
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
const frameLocator = page.frameLocator('iframe[name="embedded"]');
|
||||
// ...
|
||||
const locator = frameLocator.exitFrame();
|
||||
await expect(locator).toBeVisible();
|
||||
```
|
||||
|
||||
```java
|
||||
FrameLocator frameLocator = page.frameLocator("iframe[name=\"embedded\"]");
|
||||
// ...
|
||||
Locator locator = frameLocator.exitFrame();
|
||||
assertThat(locator).isVisible();
|
||||
```
|
||||
|
||||
```python async
|
||||
frame_locator = page.frame_locator("iframe[name=\"embedded\"]")
|
||||
# ...
|
||||
locator = frame_locator.exit_frame
|
||||
await expect(locator).to_be_visible()
|
||||
```
|
||||
|
||||
```python sync
|
||||
frame_locator = page.frame_locator("iframe[name=\"embedded\"]")
|
||||
# ...
|
||||
locator = frame_locator.exit_frame
|
||||
expect(locator).to_be_visible()
|
||||
```
|
||||
|
||||
```csharp
|
||||
var frameLocator = Page.FrameLocator("iframe[name=\"embedded\"]");
|
||||
// ...
|
||||
var locator = frameLocator.ExitFrame;
|
||||
await Expect(locator).ToBeVisibleAsync();
|
||||
```
|
||||
If you have a [FrameLocator] object it can be converted to [Locator] pointing to the same `iframe` using [`method: FrameLocator.owner`].
|
||||
|
||||
|
||||
## method: FrameLocator.first
|
||||
|
|
@ -248,3 +202,51 @@ Returns locator to the n-th matching frame. It's zero based, `nth(0)` selects th
|
|||
### param: FrameLocator.nth.index
|
||||
* since: v1.17
|
||||
- `index` <[int]>
|
||||
|
||||
## method: FrameLocator.owner
|
||||
* since: v1.43
|
||||
- returns: <[Locator]>
|
||||
|
||||
Returns a [Locator] object pointing to the same `iframe` as this frame locator.
|
||||
|
||||
Useful when you have a [FrameLocator] object obtained somewhere, and later on would like to interact with the `iframe` element.
|
||||
|
||||
For a reverse operation, use [`method: Locator.contentFrame`].
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
const frameLocator = page.frameLocator('iframe[name="embedded"]');
|
||||
// ...
|
||||
const locator = frameLocator.owner();
|
||||
await expect(locator).toBeVisible();
|
||||
```
|
||||
|
||||
```java
|
||||
FrameLocator frameLocator = page.frameLocator("iframe[name=\"embedded\"]");
|
||||
// ...
|
||||
Locator locator = frameLocator.owner();
|
||||
assertThat(locator).isVisible();
|
||||
```
|
||||
|
||||
```python async
|
||||
frame_locator = page.frame_locator("iframe[name=\"embedded\"]")
|
||||
# ...
|
||||
locator = frame_locator.owner
|
||||
await expect(locator).to_be_visible()
|
||||
```
|
||||
|
||||
```python sync
|
||||
frame_locator = page.frame_locator("iframe[name=\"embedded\"]")
|
||||
# ...
|
||||
locator = frame_locator.owner
|
||||
expect(locator).to_be_visible()
|
||||
```
|
||||
|
||||
```csharp
|
||||
var frameLocator = Page.FrameLocator("iframe[name=\"embedded\"]");
|
||||
// ...
|
||||
var locator = frameLocator.Owner;
|
||||
await Expect(locator).ToBeVisibleAsync();
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -747,7 +747,7 @@ Resolves given locator to the first matching DOM element. If there are no matchi
|
|||
|
||||
Resolves given locator to all matching DOM elements. If there are no matching elements, returns an empty list.
|
||||
|
||||
## method: Locator.enterFrame
|
||||
## method: Locator.contentFrame
|
||||
* since: v1.43
|
||||
- returns: <[FrameLocator]>
|
||||
|
||||
|
|
@ -755,40 +755,42 @@ Returns a [FrameLocator] object pointing to the same `iframe` as this locator.
|
|||
|
||||
Useful when you have a [Locator] object obtained somewhere, and later on would like to interact with the content inside the frame.
|
||||
|
||||
For a reverse operation, use [`method: FrameLocator.owner`].
|
||||
|
||||
**Usage**
|
||||
|
||||
```js
|
||||
const locator = page.locator('iframe[name="embedded"]');
|
||||
// ...
|
||||
const frameLocator = locator.enterFrame();
|
||||
const frameLocator = locator.contentFrame();
|
||||
await frameLocator.getByRole('button').click();
|
||||
```
|
||||
|
||||
```java
|
||||
Locator locator = page.locator("iframe[name=\"embedded\"]");
|
||||
// ...
|
||||
FrameLocator frameLocator = locator.enterFrame();
|
||||
FrameLocator frameLocator = locator.contentFrame();
|
||||
frameLocator.getByRole(AriaRole.BUTTON).click();
|
||||
```
|
||||
|
||||
```python async
|
||||
locator = page.locator("iframe[name=\"embedded\"]")
|
||||
# ...
|
||||
frame_locator = locator.enter_frame
|
||||
frame_locator = locator.content_frame
|
||||
await frame_locator.get_by_role("button").click()
|
||||
```
|
||||
|
||||
```python sync
|
||||
locator = page.locator("iframe[name=\"embedded\"]")
|
||||
# ...
|
||||
frame_locator = locator.enter_frame
|
||||
frame_locator = locator.content_frame
|
||||
frame_locator.get_by_role("button").click()
|
||||
```
|
||||
|
||||
```csharp
|
||||
var locator = Page.Locator("iframe[name=\"embedded\"]");
|
||||
// ...
|
||||
var frameLocator = locator.EnterFrame;
|
||||
var frameLocator = locator.ContentFrame;
|
||||
await frameLocator.GetByRole(AriaRole.Button).ClickAsync();
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -999,10 +999,11 @@ disable timeout.
|
|||
If specified, traces are saved into this directory.
|
||||
|
||||
## browser-option-devtools
|
||||
* deprecated: Use [debugging tools](../debug.md) instead.
|
||||
- `devtools` <[boolean]>
|
||||
|
||||
**Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
|
||||
**Deprecated, Chromium-only.** Use [debugging tools](../debug.md) instead.
|
||||
|
||||
Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
|
||||
[`option: headless`] option will be set `false`.
|
||||
|
||||
## browser-option-slowmo
|
||||
|
|
|
|||
|
|
@ -556,10 +556,10 @@ export default defineConfig({
|
|||
Whether to record trace for each test. Defaults to `'off'`.
|
||||
* `'off'`: Do not record trace.
|
||||
* `'on'`: Record trace for each test.
|
||||
* `'retain-on-failure'`: Record trace for each test, but remove all traces from successful test runs.
|
||||
* `'on-first-retry'`: Record trace only when retrying a test for the first time.
|
||||
* `'on-all-retries'`: Record traces only when retrying for all retries.
|
||||
* `'retain-on-first-failure'`: Record traces only when the test fails for the first time.
|
||||
* `'on-all-retries'`: Record trace only when retrying a test.
|
||||
* `'retain-on-failure'`: Record trace for each test. When test run passes, remove the recorded trace.
|
||||
* `'retain-on-first-failure'`: Record trace for the first run of each test, but not for retires. When test run passes, remove the recorded trace.
|
||||
|
||||
For more control, pass an object that specifies `mode` and trace features to enable.
|
||||
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ export class Locator implements api.Locator {
|
|||
return await this._frame.$$(this._selector);
|
||||
}
|
||||
|
||||
enterFrame() {
|
||||
contentFrame() {
|
||||
return new FrameLocator(this._frame, this._selector);
|
||||
}
|
||||
|
||||
|
|
@ -408,7 +408,7 @@ export class FrameLocator implements api.FrameLocator {
|
|||
return this.locator(getByRoleSelector(role, options));
|
||||
}
|
||||
|
||||
exitFrame() {
|
||||
owner() {
|
||||
return new Locator(this._frame, this._frameSelector);
|
||||
}
|
||||
|
||||
|
|
|
|||
103
packages/playwright-core/types/types.d.ts
vendored
103
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -11238,6 +11238,27 @@ export interface Locator {
|
|||
trial?: boolean;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Returns a {@link FrameLocator} object pointing to the same `iframe` as this locator.
|
||||
*
|
||||
* Useful when you have a {@link Locator} object obtained somewhere, and later on would like to interact with the
|
||||
* content inside the frame.
|
||||
*
|
||||
* For a reverse operation, use
|
||||
* [frameLocator.owner()](https://playwright.dev/docs/api/class-framelocator#frame-locator-owner).
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('iframe[name="embedded"]');
|
||||
* // ...
|
||||
* const frameLocator = locator.contentFrame();
|
||||
* await frameLocator.getByRole('button').click();
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
contentFrame(): FrameLocator;
|
||||
|
||||
/**
|
||||
* Returns the number of elements matching the locator.
|
||||
*
|
||||
|
|
@ -11462,24 +11483,6 @@ export interface Locator {
|
|||
*/
|
||||
elementHandles(): Promise<Array<ElementHandle>>;
|
||||
|
||||
/**
|
||||
* Returns a {@link FrameLocator} object pointing to the same `iframe` as this locator.
|
||||
*
|
||||
* Useful when you have a {@link Locator} object obtained somewhere, and later on would like to interact with the
|
||||
* content inside the frame.
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('iframe[name="embedded"]');
|
||||
* // ...
|
||||
* const frameLocator = locator.enterFrame();
|
||||
* await frameLocator.getByRole('button').click();
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
enterFrame(): FrameLocator;
|
||||
|
||||
/**
|
||||
* Set a value to the input field.
|
||||
*
|
||||
|
|
@ -13170,9 +13173,10 @@ export interface BrowserType<Unused = {}> {
|
|||
deviceScaleFactor?: number;
|
||||
|
||||
/**
|
||||
* **Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
|
||||
* `headless` option will be set `false`.
|
||||
* @deprecated Use [debugging tools](https://playwright.dev/docs/debug) instead.
|
||||
* **Deprecated, Chromium-only.** Use [debugging tools](https://playwright.dev/docs/debug) instead.
|
||||
*
|
||||
* Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the `headless` option will be
|
||||
* set `false`.
|
||||
*/
|
||||
devtools?: boolean;
|
||||
|
||||
|
|
@ -13575,9 +13579,10 @@ export interface BrowserType<Unused = {}> {
|
|||
chromiumSandbox?: boolean;
|
||||
|
||||
/**
|
||||
* **Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
|
||||
* `headless` option will be set `false`.
|
||||
* @deprecated Use [debugging tools](https://playwright.dev/docs/debug) instead.
|
||||
* **Deprecated, Chromium-only.** Use [debugging tools](https://playwright.dev/docs/debug) instead.
|
||||
*
|
||||
* Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the `headless` option will be
|
||||
* set `false`.
|
||||
*/
|
||||
devtools?: boolean;
|
||||
|
||||
|
|
@ -17783,32 +17788,14 @@ export interface FileChooser {
|
|||
* **Converting Locator to FrameLocator**
|
||||
*
|
||||
* If you have a {@link Locator} object pointing to an `iframe` it can be converted to {@link FrameLocator} using
|
||||
* [locator.enterFrame()](https://playwright.dev/docs/api/class-locator#locator-enter-frame).
|
||||
* [locator.contentFrame()](https://playwright.dev/docs/api/class-locator#locator-content-frame).
|
||||
*
|
||||
* **Converting FrameLocator to Locator**
|
||||
*
|
||||
* If you have a {@link FrameLocator} object it can be converted to {@link Locator} pointing to the same `iframe`
|
||||
* using [frameLocator.exitFrame()](https://playwright.dev/docs/api/class-framelocator#frame-locator-exit-frame).
|
||||
* using [frameLocator.owner()](https://playwright.dev/docs/api/class-framelocator#frame-locator-owner).
|
||||
*/
|
||||
export interface FrameLocator {
|
||||
/**
|
||||
* Returns a {@link Locator} object pointing to the same `iframe` as this frame locator.
|
||||
*
|
||||
* Useful when you have a {@link FrameLocator} object obtained somewhere, and later on would like to interact with the
|
||||
* `iframe` element.
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
* ```js
|
||||
* const frameLocator = page.frameLocator('iframe[name="embedded"]');
|
||||
* // ...
|
||||
* const locator = frameLocator.exitFrame();
|
||||
* await expect(locator).toBeVisible();
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
exitFrame(): Locator;
|
||||
|
||||
/**
|
||||
* Returns locator to the first matching frame.
|
||||
*/
|
||||
|
|
@ -18190,6 +18177,27 @@ export interface FrameLocator {
|
|||
* @param index
|
||||
*/
|
||||
nth(index: number): FrameLocator;
|
||||
|
||||
/**
|
||||
* Returns a {@link Locator} object pointing to the same `iframe` as this frame locator.
|
||||
*
|
||||
* Useful when you have a {@link FrameLocator} object obtained somewhere, and later on would like to interact with the
|
||||
* `iframe` element.
|
||||
*
|
||||
* For a reverse operation, use
|
||||
* [locator.contentFrame()](https://playwright.dev/docs/api/class-locator#locator-content-frame).
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
* ```js
|
||||
* const frameLocator = page.frameLocator('iframe[name="embedded"]');
|
||||
* // ...
|
||||
* const locator = frameLocator.owner();
|
||||
* await expect(locator).toBeVisible();
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
owner(): Locator;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -20270,9 +20278,10 @@ export interface LaunchOptions {
|
|||
chromiumSandbox?: boolean;
|
||||
|
||||
/**
|
||||
* **Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the
|
||||
* `headless` option will be set `false`.
|
||||
* @deprecated Use [debugging tools](https://playwright.dev/docs/debug) instead.
|
||||
* **Deprecated, Chromium-only.** Use [debugging tools](https://playwright.dev/docs/debug) instead.
|
||||
*
|
||||
* Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the `headless` option will be
|
||||
* set `false`.
|
||||
*/
|
||||
devtools?: boolean;
|
||||
|
||||
|
|
|
|||
7
packages/playwright/types/test.d.ts
vendored
7
packages/playwright/types/test.d.ts
vendored
|
|
@ -5590,10 +5590,11 @@ export interface PlaywrightWorkerOptions {
|
|||
* Whether to record trace for each test. Defaults to `'off'`.
|
||||
* - `'off'`: Do not record trace.
|
||||
* - `'on'`: Record trace for each test.
|
||||
* - `'retain-on-failure'`: Record trace for each test, but remove all traces from successful test runs.
|
||||
* - `'on-first-retry'`: Record trace only when retrying a test for the first time.
|
||||
* - `'on-all-retries'`: Record traces only when retrying for all retries.
|
||||
* - `'retain-on-first-failure'`: Record traces only when the test fails for the first time.
|
||||
* - `'on-all-retries'`: Record trace only when retrying a test.
|
||||
* - `'retain-on-failure'`: Record trace for each test. When test run passes, remove the recorded trace.
|
||||
* - `'retain-on-first-failure'`: Record trace for the first run of each test, but not for retires. When test run
|
||||
* passes, remove the recorded trace.
|
||||
*
|
||||
* For more control, pass an object that specifies `mode` and trace features to enable.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -299,22 +299,22 @@ it('should work with COEP/COOP/CORP isolated iframe', async ({ page, server, bro
|
|||
expect(await page.frames()[1].evaluate(() => window['__clicked'])).toBe(true);
|
||||
});
|
||||
|
||||
it('locator.enterFrame should work', async ({ page, server }) => {
|
||||
it('locator.contentFrame should work', async ({ page, server }) => {
|
||||
await routeIframe(page);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const locator = page.locator('iframe');
|
||||
const frameLocator = locator.enterFrame();
|
||||
const frameLocator = locator.contentFrame();
|
||||
const button = frameLocator.locator('button');
|
||||
expect(await button.innerText()).toBe('Hello iframe');
|
||||
await expect(button).toHaveText('Hello iframe');
|
||||
await button.click();
|
||||
});
|
||||
|
||||
it('frameLocator.exitFrame should work', async ({ page, server }) => {
|
||||
it('frameLocator.owner should work', async ({ page, server }) => {
|
||||
await routeIframe(page);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const frameLocator = page.frameLocator('iframe');
|
||||
const locator = frameLocator.exitFrame();
|
||||
const locator = frameLocator.owner();
|
||||
await expect(locator).toBeVisible();
|
||||
expect(await locator.getAttribute('name')).toBe('frame1');
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue