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:
Dmitry Gozman 2024-03-25 07:42:13 -07:00 committed by GitHub
parent 7a3c002944
commit 95d649b406
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 130 additions and 115 deletions

View file

@ -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();
```

View file

@ -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();
```

View file

@ -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

View file

@ -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.

View file

@ -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);
}

View file

@ -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;

View file

@ -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.
*

View file

@ -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');
});