docs: migrate JS assertions over to Java/Python assertions (#10431)

This commit is contained in:
Max Schmitt 2021-11-24 21:58:35 +01:00 committed by GitHub
parent af4a1c2d26
commit af28a779be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 195 additions and 271 deletions

View file

@ -1,7 +1,7 @@
# class: LocatorAssertions
* langs: java, python
* langs: java, python, js
The [LocatorAssertions] class provides assertion methods that can be used to make assertions about the [Locator] state in the tests. A new instance of [LocatorAssertions] is created by calling [`method: PlaywrightAssertions.assertThatLocator`]:
The [LocatorAssertions] class provides assertion methods that can be used to make assertions about the [Locator] state in the tests. A new instance of [LocatorAssertions] is created by calling [`method: PlaywrightAssertions.expectLocator`]:
```java
...
@ -19,7 +19,7 @@ public class TestLocator {
```
## method: LocatorAssertions.not
* langs: java
* langs: java, js
- returns: <[LocatorAssertions]>
Makes the assertion check for the opposite condition. For example, this code tests that the Locator doesn't contain text `"error"`:
@ -225,6 +225,11 @@ Expected value.
Ensures the [Locator] points to a checked input.
```js
const locator = page.locator('.subscribe');
await expect(locator).toBeChecked();
```
```java
assertThat(page.locator(".subscribe")).isChecked();
```
@ -239,6 +244,11 @@ assertThat(page.locator(".subscribe")).isChecked();
Ensures the [Locator] points to a disabled element.
```js
const locator = page.locator('button.submit');
await expect(locator).toBeDisabled();
```
```java
assertThat(page.locator("button.submit")).isDisabled();
```
@ -252,6 +262,11 @@ assertThat(page.locator("button.submit")).isDisabled();
Ensures the [Locator] points to an editable element.
```js
const locator = page.locator('input');
await expect(locator).toBeEditable();
```
```java
assertThat(page.locator("input")).isEditable();
```
@ -265,6 +280,11 @@ assertThat(page.locator("input")).isEditable();
Ensures the [Locator] points to an empty editable element or to a DOM node that has no text.
```js
const locator = page.locator('div.warning');
await expect(locator).toBeEmpty();
```
```java
assertThat(page.locator("div.warning")).isEmpty();
```
@ -278,6 +298,11 @@ assertThat(page.locator("div.warning")).isEmpty();
Ensures the [Locator] points to an enabled element.
```js
const locator = page.locator('button.submit');
await expect(locator).toBeEnabled();
```
```java
assertThat(page.locator("button.submit")).isEnabled();
```
@ -291,6 +316,11 @@ assertThat(page.locator("button.submit")).isEnabled();
Ensures the [Locator] points to a focused DOM node.
```js
const locator = page.locator('input');
await expect(locator).toBeFocused();
```
```java
assertThat(page.locator("input")).isFocused();
```
@ -304,6 +334,11 @@ assertThat(page.locator("input")).isFocused();
Ensures the [Locator] points to a hidden DOM node, which is the opposite of [visible](./actionability.md#visible).
```js
const locator = page.locator('.my-element');
await expect(locator).toBeHidden();
```
```java
assertThat(page.locator(".my-element")).isHidden();
```
@ -317,6 +352,11 @@ assertThat(page.locator(".my-element")).isHidden();
Ensures the [Locator] points to a [visible](./actionability.md#visible) DOM node.
```js
const locator = page.locator('.my-element');
await expect(locator).toBeVisible();
```
```java
assertThat(page.locator(".my-element")).toBeVisible();
```
@ -329,18 +369,29 @@ assertThat(page.locator(".my-element")).toBeVisible();
Ensures the [Locator] points to an element that contains the given text. You can use regular expressions for the value as well.
```js
const locator = page.locator('.title');
await expect(locator).toContainText('substring');
await expect(locator).toContainText(/\d messages/);
```
```java
assertThat(page.locator(".title")).containsText("substring");
```
Note that if array is passed as an expected value, entire lists can be asserted:
```js
const locator = page.locator('list > .list-item');
await expect(locator).toContainText(['Text 1', 'Text 4', 'Text 5']);
```
```java
assertThat(page.locator("list > .list-item")).containsText(new String[] {"Text 1", "Text 4", "Text 5"});
```
### param: LocatorAssertions.toContainText.expected
* langs: python
* langs: python, js
- `expected` <[string]|[RegExp]|[Array]<[string]|[RegExp]>>
Expected substring or RegExp or a list of those.
@ -365,6 +416,11 @@ Whether to use `element.innerText` instead of `element.textContent` when retriev
Ensures the [Locator] points to an element with given attribute.
```js
const locator = page.locator('input');
await expect(locator).toHaveAttribute('type', 'text');
```
```java
assertThat(page.locator("input")).hasAttribute("type", "text");
```
@ -387,18 +443,28 @@ Expected attribute value.
Ensures the [Locator] points to an element with given CSS class.
```js
const locator = page.locator('#component');
await expect(locator).toHaveClass(/selected/);
```
```java
assertThat(page.locator("#component")).hasClass(Pattern.compile("selected"));
```
Note that if array is passed as an expected value, entire lists can be asserted:
```js
const locator = page.locator('list > .component');
await expect(locator).toHaveClass(['component', 'component selected', 'component']);
```
```java
assertThat(page.locator("list > .component")).hasClass(new String[] {"component", "component selected", "component"});
```
### param: LocatorAssertions.toHaveClass.expected
* langs: python
* langs: python, js
- `expected` <[string]|[RegExp]|[Array]<[string]|[RegExp]>>
Expected class or RegExp or a list of those.
@ -418,6 +484,11 @@ Expected class or RegExp or a list of those.
Ensures the [Locator] resolves to an exact number of DOM nodes.
```js
const list = page.locator('list > .component');
await expect(list).toHaveCount(3);
```
```java
assertThat(page.locator("list > .component")).hasCount(3);
```
@ -435,6 +506,11 @@ Expected count.
Ensures the [Locator] resolves to an element with the given computed CSS style.
```js
const locator = page.locator('button');
await expect(locator).toHaveCSS('display', 'flex');
```
```java
assertThat(page.locator("button")).hasCSS("display", "flex");
```
@ -457,6 +533,11 @@ CSS property value.
Ensures the [Locator] points to an element with the given DOM Node ID.
```js
const locator = page.locator('input');
await expect(locator).toHaveId('lastname');
```
```java
assertThat(page.locator("input")).hasId("lastname");
```
@ -473,7 +554,13 @@ Element id.
* langs:
- alias-java: hasJSProperty
Ensures the [Locator] points to an element with given JavaScript property. Note that this property can be of a primitive type as well as a plain serializable JavaScript object.
Ensures the [Locator] points to an element with given JavaScript property. Note that this property can be
of a primitive type as well as a plain serializable JavaScript object.
```js
const locator = page.locator('.component');
await expect(locator).toHaveJSProperty('loaded', true);
```
```java
assertThat(page.locator("input")).hasJSProperty("type", "text");
@ -497,6 +584,12 @@ Property value.
Ensures the [Locator] points to an element with the given text. You can use regular expressions for the value as well.
```js
const locator = page.locator('.title');
await expect(locator).toHaveText(/Welcome, Test User/);
await expect(locator).toHaveText(/Welcome, .*/);
```
```java
assertThat(page.locator(".title")).hasText("Welcome, Test User");
assertThat(page.locator(".title")).hasText(Pattern.compile("Welcome, .*"));
@ -504,12 +597,17 @@ assertThat(page.locator(".title")).hasText(Pattern.compile("Welcome, .*"));
Note that if array is passed as an expected value, entire lists can be asserted:
```js
const locator = page.locator('list > .component');
await expect(locator).toHaveText(['Text 1', 'Text 2', 'Text 3']);
```
```java
assertThat(page.locator("list > .component")).hasText(new String[] {"Text 1", "Text 2", "Text 3"});
```
### param: LocatorAssertions.toHaveText.expected
* langs: python
* langs: python, js
- `expected` <[string]|[RegExp]|[Array]<[string]|[RegExp]>>
Expected substring or RegExp or a list of those.
@ -533,6 +631,11 @@ Whether to use `element.innerText` instead of `element.textContent` when retriev
Ensures the [Locator] points to an element with the given input value. You can use regular expressions for the value as well.
```js
const locator = page.locator('input[type=number]');
await expect(locator).toHaveValue(/[0-9]/);
```
```java
assertThat(page.locator("input[type=number]")).hasValue(Pattern.compile("[0-9]"));
```

View file

@ -1,7 +1,7 @@
# class: PageAssertions
* langs: java, python
* langs: java, python, js
The [PageAssertions] class provides assertion methods that can be used to make assertions about the [Page] state in the tests. A new instance of [LocatorAssertions] is created by calling [`method: PlaywrightAssertions.assertThatPage`]:
The [PageAssertions] class provides assertion methods that can be used to make assertions about the [Page] state in the tests. A new instance of [LocatorAssertions] is created by calling [`method: PlaywrightAssertions.expectPage`]:
```java
...
@ -20,7 +20,7 @@ public class TestPage {
## method: PageAssertions.not
* langs: java
* langs: java, js
- returns: <[PageAssertions]>
Makes the assertion check for the opposite condition. For example, this code tests that the page URL doesn't contain `"error"`:
@ -61,6 +61,10 @@ Expected substring or RegExp.
Ensures the page has the given title.
```js
await expect(page).toHaveTitle(/.*checkout/);
```
```java
assertThat(page).hasTitle("Playwright");
```
@ -78,6 +82,10 @@ Expected title or RegExp.
Ensures the page is navigated to the given URL.
```js
await expect(page).toHaveURL(/.*checkout/);
```
```java
assertThat(page).hasURL(".com");
```

View file

@ -1,10 +1,36 @@
# class: PlaywrightAssertions
* langs: java, python
* langs: java, python, js
The [PlaywrightAssertions] class provides convenience methods for creating assertions that will wait until the expected condition is met.
Consider the following example:
```js
import { test, expect } from '@playwright/test';
test('status becomes submitted', async ({ page }) => {
// ...
await page.click('#submit-button')
await expect(page.locator('.status')).toHaveText('Submitted');
});
```
```python async
from playwright.async_api import Page, expect
async def test_assertions_page_to_have_title(page: Page) -> None:
await page.click('#submit-button')
await expect(page.locator('.status')).to_have_text('Submitted')
```
```python sync
from playwright.sync_api import Page, expect
def test_assertions_page_to_have_title(page: Page) -> None:
page.click('#submit-button')
expect(page.locator('.status')).to_have_text('Submitted')
```
```java
...
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
@ -26,9 +52,9 @@ reached. You can pass this timeout as an option.
By default, the timeout for assertions is set to 5 seconds.
To use Playwright assertions add the following dependency into the `pom.xml` of your Maven project:
**langs: java**To use Playwright assertions add the following dependency into the `pom.xml` of your Maven project:
```xml
```xml java
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>assertions</artifactId>
@ -36,10 +62,11 @@ To use Playwright assertions add the following dependency into the `pom.xml` of
</dependency>
```
## method: PlaywrightAssertions.assertThatLocator
* langs: java, python
## method: PlaywrightAssertions.expectLocator
* langs: java, python, js
- alias-java: assertThat
- alias-python: expect
- alias-js: expect
- returns: <[LocatorAssertions]>
Creates a [LocatorAssertions] object for the given [Locator].
@ -48,15 +75,16 @@ Creates a [LocatorAssertions] object for the given [Locator].
PlaywrightAssertions.assertThat(locator).isVisible();
```
### param: PlaywrightAssertions.assertThatLocator.locator
### param: PlaywrightAssertions.expectLocator.locator
- `locator` <[Locator]>
[Locator] object to use for assertions.
## method: PlaywrightAssertions.assertThatPage
* langs: java, python
## method: PlaywrightAssertions.expectPage
* langs: java, python, js
- alias-java: assertThat
- alias-python: expect
- alias-js: expect
- returns: <[PageAssertions]>
Creates a [PageAssertions] object for the given [Page].
@ -65,7 +93,7 @@ Creates a [PageAssertions] object for the given [Page].
PlaywrightAssertions.assertThat(page).hasTitle("News");
```
### param: PlaywrightAssertions.assertThatPage.page
### param: PlaywrightAssertions.expectPage.page
- `page` <[Page]>
[Page] object to use for assertions.

View file

@ -708,6 +708,13 @@ Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeou
using the [`method: AndroidDevice.setDefaultTimeout`] method.
## assertions-timeout
* langs: js
- `timeout` <[float]>
Time to retry the assertion for. Defaults to `timeout` in [`property: TestConfig.expect`].
## assertions-timeout
* langs: java, python
- `timeout` <[float]>
Time to retry the assertion for.

View file

@ -20,6 +20,25 @@ await expect(locator).not.toContainText("some text");
```
<!-- TOC -->
- [`method: LocatorAssertions.toBeChecked`]
- [`method: LocatorAssertions.toBeDisabled`]
- [`method: LocatorAssertions.toBeEditable`]
- [`method: LocatorAssertions.toBeEmpty`]
- [`method: LocatorAssertions.toBeEnabled`]
- [`method: LocatorAssertions.toBeFocused`]
- [`method: LocatorAssertions.toBeHidden`]
- [`method: LocatorAssertions.toBeVisible`]
- [`method: LocatorAssertions.toContainText`]
- [`method: LocatorAssertions.toHaveAttribute`]
- [`method: LocatorAssertions.toHaveClass`]
- [`method: LocatorAssertions.toHaveCount`]
- [`method: LocatorAssertions.toHaveCSS`]
- [`method: LocatorAssertions.toHaveId`]
- [`method: LocatorAssertions.toHaveJSProperty`]
- [`method: LocatorAssertions.toHaveText`]
- [`method: LocatorAssertions.toHaveValue`]
- [`method: PageAssertions.toHaveTitle`]
- [`method: PageAssertions.toHaveURL`]
## Matching
@ -36,253 +55,6 @@ in test config.
By default, the timeout for assertions is set to 5 seconds. Learn more about [various timeouts](./test-timeouts.md).
## expect(locator).toBeChecked([options])
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to the checked input.
```js
const locator = page.locator('.subscribe');
await expect(locator).toBeChecked();
```
## expect(locator).toBeDisabled([options])
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to a disabled element.
```js
const locator = page.locator('button.submit');
await expect(locator).toBeDisabled();
```
## expect(locator).toBeEditable([options])
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to an editable element.
```js
const locator = page.locator('input');
await expect(locator).toBeEditable();
```
## expect(locator).toBeEmpty([options])
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to an empty editable element or to a DOM node that has no text.
```js
const locator = page.locator('div.warning');
await expect(locator).toBeEmpty();
```
## expect(locator).toBeEnabled([options])
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to an enabled element.
```js
const locator = page.locator('button.submit');
await expect(locator).toBeEnabled();
```
## expect(locator).toBeFocused([options])
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to a focused DOM node.
```js
const locator = page.locator('input');
await expect(locator).toBeFocused();
```
## expect(locator).toBeHidden([options])
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to a hidden DOM node, which is the opposite of [visible](./actionability.md#visible).
```js
const locator = page.locator('.my-element');
await expect(locator).toBeHidden();
```
## expect(locator).toBeVisible([options])
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to a [visible](./actionability.md#visible) DOM node.
```js
const locator = page.locator('.my-element');
await expect(locator).toBeVisible();
```
## expect(locator).toContainText(expected[, options])
- `expected` <[string] | [RegExp] | [Array]<[string]|[RegExp]>>
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
- `useInnerText` <[boolean]> Whether to use `element.innerText` instead of `element.textContent` when retrieving DOM node text.
Ensures [Locator] points to an element that contains the given text. You can use regular expressions for the value as well.
```js
const locator = page.locator('.title');
await expect(locator).toContainText('substring');
await expect(locator).toContainText(/\d messages/);
```
Note that if array is passed as an expected value, entire lists can be asserted:
```js
const locator = page.locator('list > .list-item');
await expect(locator).toContainText(['Text 1', 'Text 4', 'Text 5']);
```
## expect(locator).toHaveAttribute(name, value[, options])
- `name` <[string]> Attribute name
- `value` <[string]|[RegExp]> Attribute value
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to an element with given attribute.
```js
const locator = page.locator('input');
await expect(locator).toHaveAttribute('type', 'text');
```
## expect(locator).toHaveClass(expected[, options])
- `expected` <[string] | [RegExp] | [Array]<[string]|[RegExp]>>
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to an element with given CSS class.
```js
const locator = page.locator('#component');
await expect(locator).toHaveClass(/selected/);
```
Note that if array is passed as an expected value, entire lists can be asserted:
```js
const locator = page.locator('list > .component');
await expect(locator).toHaveClass(['component', 'component selected', 'component']);
```
## expect(locator).toHaveCount(count[, options])
- `count` <[number]>
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] resolves to an exact number of DOM nodes.
```js
const list = page.locator('list > .component');
await expect(list).toHaveCount(3);
```
## expect(locator).toHaveCSS(name, value[, options])
- `name` <[string]> CSS property name
- `value` <[string]|[RegExp]> CSS property value
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] resolves to an element with the given computed CSS style.
```js
const locator = page.locator('button');
await expect(locator).toHaveCSS('display', 'flex');
```
## expect(locator).toHaveId(id[, options])
- `id` <[string]> Element id
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to an element with the given DOM Node ID.
```js
const locator = page.locator('input');
await expect(locator).toHaveId('lastname');
```
## expect(locator).toHaveJSProperty(name, value[, options])
- `name` <[string]> Property name
- `value` <[any]> Property value
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to an element with given JavaScript property. Note that this property can be
of a primitive type as well as a plain serializable JavaScript object.
```js
const locator = page.locator('.component');
await expect(locator).toHaveJSProperty('loaded', true);
```
## expect(locator).toHaveText(expected[, options])
- `expected` <[string] | [RegExp] | [Array]<[string]|[RegExp]>>
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
- `useInnerText` <[boolean]> Whether to use `element.innerText` instead of `element.textContent` when retrieving DOM node text.
Ensures [Locator] points to an element with the given text. You can use regular expressions for the value as well.
```js
const locator = page.locator('.title');
await expect(locator).toHaveText(/Welcome, Test User/);
await expect(locator).toHaveText(/Welcome, .*/);
```
Note that if array is passed as an expected value, entire lists can be asserted:
```js
const locator = page.locator('list > .component');
await expect(locator).toHaveText(['Text 1', 'Text 2', 'Text 3']);
```
## expect(locator).toHaveValue(value[, options])
- `value` <[string] | [RegExp]>
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures [Locator] points to an element with the given input value. You can use regular expressions for the value as well.
```js
const locator = page.locator('input[type=number]');
await expect(locator).toHaveValue(/[0-9]/);
```
## expect(page).toHaveTitle(title[, options])
- `title` <[string] | [RegExp]>
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures page has a given title.
```js
await expect(page).toHaveTitle(/.*checkout/);
```
## expect(page).toHaveURL(url[, options])
- `url` <[string] | [RegExp]>
- `options`
- `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`].
Ensures page is navigated to a given URL.
```js
await expect(page).toHaveURL(/.*checkout/);
```
## expect(value).toMatchSnapshot(name[, options])
- `name` <[string] | [Array]<[string]>> Snapshot name.
- `options`

View file

@ -22,6 +22,8 @@ const path = require('path');
/** @typedef {import('../../markdown').MarkdownNode} MarkdownNode */
const IGNORE_CLASSES = ['PlaywrightAssertions', 'LocatorAssertions', 'PageAssertions'];
module.exports = function lint(documentation, jsSources, apiFileName) {
const errors = [];
documentation.copyDocsFromSuperclasses(errors);
@ -46,6 +48,8 @@ module.exports = function lint(documentation, jsSources, apiFileName) {
}
}
for (const cls of documentation.classesArray) {
if (IGNORE_CLASSES.includes(cls.name))
continue;
const methods = apiMethods.get(cls.name);
if (!methods) {
errors.push(`Documented "${cls.name}" not found in sources`);
@ -114,10 +118,6 @@ function listMethods(rootNames, apiFileName) {
* @param {string} methodName
*/
function shouldSkipMethodByName(className, methodName) {
if (methodName === '_request' && (className === 'BrowserContext' || className === 'Page'))
return false;
if (methodName === '_newRequest' && className === 'Playwright')
return false;
if (methodName.startsWith('_') || methodName === 'T' || methodName === 'toString')
return true;
if (/** @type {any} */(EventEmitter).prototype.hasOwnProperty(methodName))

View file

@ -109,7 +109,8 @@ class TypesGenerator {
return (!docsOnlyClassMapping && docClass) ? this.classBody(docClass) : '';
});
const classes = this.documentation.classesArray.filter(cls => !handledClasses.has(cls.name));
const IGNORED_CLASSES = ['PlaywrightAssertions', 'LocatorAssertions', 'PageAssertions'];
const classes = this.documentation.classesArray.filter(cls => !IGNORED_CLASSES.includes(cls.name)).filter(cls => !handledClasses.has(cls.name));
{
const playwright = this.documentation.classesArray.find(c => c.name === 'Playwright');
playwright.membersArray = playwright.membersArray.filter(member => !['errors', 'devices'].includes(member.name));

View file

@ -193,6 +193,11 @@ function buildTree(lines) {
else
node.liType = 'default';
}
const match = node.text.match(/\*\*langs: (.*)\*\*(.*)/);
if (match) {
node.codeLang = match[1];
node.text = match[2];
}
appendNode(indent, node);
}
return root.children;