Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: lint java docs snippets #32945

Merged
merged 2 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
run: npm audit --omit dev
lint-snippets:
name: "Lint snippets"
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -50,6 +50,12 @@ jobs:
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '21'
- run: npm ci
- run: pip install -r utils/doclint/linting-code-snippets/python/requirements.txt
- run: mvn package
working-directory: utils/doclint/linting-code-snippets/java
- run: node utils/doclint/linting-code-snippets/cli.js
96 changes: 50 additions & 46 deletions docs/src/accessibility-testing-java.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,24 @@ For example, you can use [`AxeBuilder.include()`](https://github.com/dequelabs/a
`AxeBuilder.analyze()` will scan the page *in its current state* when you call it. To scan parts of a page that are revealed based on UI interactions, use [Locators](./locators.md) to interact with the page before invoking `analyze()`:

```java
@Test
void navigationMenuFlyoutShouldNotHaveAutomaticallyDetectableAccessibilityViolations() throws Exception {
page.navigate("https://your-site.com/");
public class HomepageTests {
@Test
void navigationMenuFlyoutShouldNotHaveAutomaticallyDetectableAccessibilityViolations() throws Exception {
page.navigate("https://your-site.com/");

page.locator("button[aria-label=\"Navigation Menu\"]").click();
page.locator("button[aria-label=\"Navigation Menu\"]").click();

// It is important to waitFor() the page to be in the desired
// state *before* running analyze(). Otherwise, axe might not
// find all the elements your test expects it to scan.
page.locator("#navigation-menu-flyout").waitFor();
// It is important to waitFor() the page to be in the desired
// state *before* running analyze(). Otherwise, axe might not
// find all the elements your test expects it to scan.
page.locator("#navigation-menu-flyout").waitFor();

AxeResults accessibilityScanResults = new AxeBuilder(page)
.include(Arrays.asList("#navigation-menu-flyout"))
.analyze();
AxeResults accessibilityScanResults = new AxeBuilder(page)
.include(Arrays.asList("#navigation-menu-flyout"))
.analyze();

assertEquals(Collections.emptyList(), accessibilityScanResults.getViolations());
assertEquals(Collections.emptyList(), accessibilityScanResults.getViolations());
}
}
```

Expand Down Expand Up @@ -158,38 +160,40 @@ This approach avoids the downsides of using `AxeBuilder.exclude()` at the cost o
Here is an example of using fingerprints based on only rule IDs and "target" selectors pointing to each violation:

```java
@Test
shouldOnlyHaveAccessibilityViolationsMatchingKnownFingerprints() throws Exception {
page.navigate("https://your-site.com/");
public class HomepageTests {
@Test
shouldOnlyHaveAccessibilityViolationsMatchingKnownFingerprints() throws Exception {
page.navigate("https://your-site.com/");

AxeResults accessibilityScanResults = new AxeBuilder(page).analyze();
AxeResults accessibilityScanResults = new AxeBuilder(page).analyze();

List<ViolationFingerprint> violationFingerprints = fingerprintsFromScanResults(accessibilityScanResults);
List<ViolationFingerprint> violationFingerprints = fingerprintsFromScanResults(accessibilityScanResults);

assertEquals(Arrays.asList(
new ViolationFingerprint("aria-roles", "[span[role=\"invalid\"]]"),
new ViolationFingerprint("color-contrast", "[li:nth-child(2) > span]"),
new ViolationFingerprint("label", "[input]")
), violationFingerprints);
}
assertEquals(Arrays.asList(
new ViolationFingerprint("aria-roles", "[span[role=\"invalid\"]]"),
new ViolationFingerprint("color-contrast", "[li:nth-child(2) > span]"),
new ViolationFingerprint("label", "[input]")
), violationFingerprints);
}

// You can make your "fingerprint" as specific as you like. This one considers a violation to be
// "the same" if it corresponds the same Axe rule on the same element.
//
// Using a record type makes it easy to compare fingerprints with assertEquals
public record ViolationFingerprint(String ruleId, String target) { }

public List<ViolationFingerprint> fingerprintsFromScanResults(AxeResults results) {
return results.getViolations().stream()
// Each violation refers to one rule and multiple "nodes" which violate it
.flatMap(violation -> violation.getNodes().stream()
.map(node -> new ViolationFingerprint(
violation.getId(),
// Each node contains a "target", which is a CSS selector that uniquely identifies it
// If the page involves iframes or shadow DOMs, it may be a chain of CSS selectors
node.getTarget().toString()
)))
.collect(Collectors.toList());
// You can make your "fingerprint" as specific as you like. This one considers a violation to be
// "the same" if it corresponds the same Axe rule on the same element.
//
// Using a record type makes it easy to compare fingerprints with assertEquals
public record ViolationFingerprint(String ruleId, String target) { }

public List<ViolationFingerprint> fingerprintsFromScanResults(AxeResults results) {
return results.getViolations().stream()
// Each violation refers to one rule and multiple "nodes" which violate it
.flatMap(violation -> violation.getNodes().stream()
.map(node -> new ViolationFingerprint(
violation.getId(),
// Each node contains a "target", which is a CSS selector that uniquely identifies it
// If the page involves iframes or shadow DOMs, it may be a chain of CSS selectors
node.getTarget().toString()
)))
.collect(Collectors.toList());
}
}
```

Expand All @@ -208,11 +212,11 @@ This example fixture creates an `AxeBuilder` object which is pre-configured with

```java
class AxeTestFixtures extends TestFixtures {
AxeBuilder makeAxeBuilder() {
return new AxeBuilder(page)
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
.exclude('#commonly-reused-element-with-known-issue');
}
AxeBuilder makeAxeBuilder() {
return new AxeBuilder(page)
.withTags(new String[]{"wcag2a", "wcag2aa", "wcag21a", "wcag21aa"})
.exclude("#commonly-reused-element-with-known-issue");
}
}
```

Expand All @@ -229,7 +233,7 @@ public class HomepageTests extends AxeTestFixtures {
AxeResults accessibilityScanResults = makeAxeBuilder()
// Automatically uses the shared AxeBuilder configuration,
// but supports additional test-specific configuration too
.include('#specific-element-under-test')
.include("#specific-element-under-test")
.analyze();

assertEquals(Collections.emptyList(), accessibilityScanResults.getViolations());
Expand Down
54 changes: 30 additions & 24 deletions docs/src/api-testing-java.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ public class TestGitHubAPI {
These tests assume that repository exists. You probably want to create a new one before running tests and delete it afterwards. Use `@BeforeAll` and `@AfterAll` hooks for that.

```java
public class TestGitHubAPI {
// ...

void createTestRepository() {
Expand Down Expand Up @@ -223,6 +224,7 @@ These tests assume that repository exists. You probably want to create a new one
disposeAPIRequestContext();
closePlaywright();
}
}
```

### Complete test example
Expand Down Expand Up @@ -381,18 +383,20 @@ The following test creates a new issue via API and then navigates to the list of
project to check that it appears at the top of the list. The check is performed using [LocatorAssertions].

```java
@Test
void lastCreatedIssueShouldBeFirstInTheList() {
Map<String, String> data = new HashMap<>();
data.put("title", "[Feature] request 1");
data.put("body", "Feature description");
APIResponse newIssue = request.post("/repos/" + USER + "/" + REPO + "/issues",
RequestOptions.create().setData(data));
assertTrue(newIssue.ok());

page.navigate("https://github.com/" + USER + "/" + REPO + "/issues");
Locator firstIssue = page.locator("a[data-hovercard-type='issue']").first();
assertThat(firstIssue).hasText("[Feature] request 1");
public class TestGitHubAPI {
@Test
void lastCreatedIssueShouldBeFirstInTheList() {
Map<String, String> data = new HashMap<>();
data.put("title", "[Feature] request 1");
data.put("body", "Feature description");
APIResponse newIssue = request.post("/repos/" + USER + "/" + REPO + "/issues",
RequestOptions.create().setData(data));
assertTrue(newIssue.ok());

page.navigate("https://github.com/" + USER + "/" + REPO + "/issues");
Locator firstIssue = page.locator("a[data-hovercard-type='issue']").first();
assertThat(firstIssue).hasText("[Feature] request 1");
}
}
```

Expand All @@ -402,18 +406,20 @@ The following test creates a new issue via user interface in the browser and the
it was created:

```java
@Test
void lastCreatedIssueShouldBeOnTheServer() {
page.navigate("https://github.com/" + USER + "/" + REPO + "/issues");
page.locator("text=New Issue").click();
page.locator("[aria-label='Title']").fill("Bug report 1");
page.locator("[aria-label='Comment body']").fill("Bug description");
page.locator("text=Submit new issue").click();
String issueId = page.url().substring(page.url().lastIndexOf('/'));

APIResponse newIssue = request.get("https://github.com/" + USER + "/" + REPO + "/issues/" + issueId);
assertThat(newIssue).isOK();
assertTrue(newIssue.text().contains("Bug report 1"));
public class TestGitHubAPI {
@Test
void lastCreatedIssueShouldBeOnTheServer() {
page.navigate("https://github.com/" + USER + "/" + REPO + "/issues");
page.locator("text=New Issue").click();
page.locator("[aria-label='Title']").fill("Bug report 1");
page.locator("[aria-label='Comment body']").fill("Bug description");
page.locator("text=Submit new issue").click();
String issueId = page.url().substring(page.url().lastIndexOf('/'));

APIResponse newIssue = request.get("https://github.com/" + USER + "/" + REPO + "/issues/" + issueId);
assertThat(newIssue).isOK();
assertTrue(newIssue.text().contains("Bug report 1"));
}
}
```

Expand Down
8 changes: 4 additions & 4 deletions docs/src/api/class-apiresponseassertions.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ test('navigates to login', async ({ page }) => {
```

```java
...
// ...
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;

public class TestPage {
...
// ...
@Test
void navigatesToLoginPage() {
...
APIResponse response = page.request().get('https://playwright.dev');
// ...
APIResponse response = page.request().get("https://playwright.dev");
assertThat(response).isOK();
}
}
Expand Down
22 changes: 11 additions & 11 deletions docs/src/api/class-browser.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'.
import com.microsoft.playwright.*;

public class Example {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
BrowserType firefox = playwright.firefox()
Browser browser = firefox.launch();
Page page = browser.newPage();
page.navigate('https://example.com');
browser.close();
}
}
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
BrowserType firefox = playwright.firefox();
Browser browser = firefox.launch();
Page page = browser.newPage();
page.navigate("https://example.com");
browser.close();
}
}
}
```

Expand Down Expand Up @@ -202,7 +202,7 @@ Browser browser = playwright.firefox().launch(); // Or 'chromium' or 'webkit'.
BrowserContext context = browser.newContext();
// Create a new page in a pristine context.
Page page = context.newPage();
page.navigate('https://example.com');
page.navigate("https://example.com");

// Graceful close up everything
context.close();
Expand Down Expand Up @@ -331,7 +331,7 @@ await browser.stopTracing();
```java
browser.startTracing(page, new Browser.StartTracingOptions()
.setPath(Paths.get("trace.json")));
page.goto('https://www.google.com');
page.navigate("https://www.google.com");
browser.stopTracing();
```

Expand Down
5 changes: 3 additions & 2 deletions docs/src/api/class-browsercontext.md
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ import com.microsoft.playwright.*;
public class Example {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
BrowserType webkit = playwright.webkit()
BrowserType webkit = playwright.webkit();
Browser browser = webkit.launch(new BrowserType.LaunchOptions().setHeadless(false));
BrowserContext context = browser.newContext();
context.exposeBinding("pageURL", (source, args) -> source.page().url());
Expand Down Expand Up @@ -813,8 +813,9 @@ import java.util.Base64;
public class Example {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
BrowserType webkit = playwright.webkit()
BrowserType webkit = playwright.webkit();
Browser browser = webkit.launch(new BrowserType.LaunchOptions().setHeadless(false));
BrowserContext context = browser.newContext();
context.exposeFunction("sha256", args -> {
String text = (String) args[0];
MessageDigest crypto;
Expand Down
4 changes: 2 additions & 2 deletions docs/src/api/class-consolemessage.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ ConsoleMessage msg = page.waitForConsoleMessage(() -> {
});

// Deconstruct console.log arguments
msg.args().get(0).jsonValue() // hello
msg.args().get(1).jsonValue() // 42
msg.args().get(0).jsonValue(); // hello
msg.args().get(1).jsonValue(); // 42
```

```python async
Expand Down
6 changes: 3 additions & 3 deletions docs/src/api/class-formdata.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The [FormData] is used create form data that is sent via [APIRequestContext].

```java
import com.microsoft.playwright.options.FormData;
...
// ...
FormData form = FormData.create()
.set("firstName", "John")
.set("lastName", "Doe")
Expand All @@ -28,7 +28,7 @@ the new value onto the end of the existing set of values.

```java
import com.microsoft.playwright.options.FormData;
...
// ...
FormData form = FormData.create()
// Only name and value are set.
.append("firstName", "John")
Expand Down Expand Up @@ -100,7 +100,7 @@ Sets a field on the form. File values can be passed either as `Path` or as `File

```java
import com.microsoft.playwright.options.FormData;
...
// ...
FormData form = FormData.create()
// Only name and value are set.
.set("firstName", "John")
Expand Down
2 changes: 1 addition & 1 deletion docs/src/api/class-keyboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ await browser.close();
Page page = browser.newPage();
page.navigate("https://keycode.info");
page.keyboard().press("A");
page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("A.png"));
page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("A.png")));
page.keyboard().press("ArrowLeft");
page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("ArrowLeft.png")));
page.keyboard().press("Shift+O");
Expand Down
2 changes: 1 addition & 1 deletion docs/src/api/class-locator.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ for li in page.get_by_role('listitem').all():
```

```java
for (Locator li : page.getByRole('listitem').all())
for (Locator li : page.getByRole("listitem").all())
li.click();
```

Expand Down
Loading