Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Switch `page.locator` with `page.getByRole` and `page.getByText`
Sebastian Martinez committed 2 years ago
commit afbc57079bb6d7a1a566948ec8a12821e9a33d65
parent 6151729a6d4555076a903e415762ffcc8d9a6e79
15 files changed +140 -160
modified src/App/Header.svelte
@@ -72,7 +72,7 @@
    </div>
    <Floating>
      <div slot="toggle">
-
        <button class="toggle" name="Settings">
+
        <button class="toggle" aria-label="Settings" name="Settings">
          <Icon name="gear" />
        </button>
      </div>
modified tests/build/smoke.spec.ts
@@ -6,8 +6,8 @@ test("exceptions in production build", async ({ page }) => {
  // happen after the page has been painted.
  await page.waitForTimeout(2000);
  await expect(
-
    page.locator(
-
      "text=Radicle enables developers to securely collaborate on software over a peer-to-peer network built on Git.",
+
    page.getByText(
+
      "Radicle enables developers to securely collaborate on software over a peer-to-peer network built on Git.",
    ),
  ).toBeVisible();
});
modified tests/e2e/clipboard.spec.ts
@@ -42,16 +42,16 @@ test("copy to clipboard", async ({ page, browserName, context }) => {

  // `rad clone` URL.
  {
-
    await page.locator('role=button[name="Clone"]').click();
-
    await page.locator("text=rad clone").hover();
-
    await page.locator("text=rad clone").locator(".clipboard").first().click();
+
    await page.getByRole("button", { name: "Clone" }).click();
+
    await page.getByText("rad clone").hover();
+
    await page.getByText("rad clone").locator(".clipboard").first().click();
    await expectClipboard(`rad clone ${sourceBrowsingRid}`, page);
  }

  // `git clone` URL.
  {
-
    await page.locator("text=git clone").hover();
-
    await page.locator("text=git clone").locator(".clipboard").first().click();
+
    await page.getByText("git clone").hover();
+
    await page.getByText("git clone").locator(".clipboard").first().click();
    await expectClipboard(
      `git clone http://127.0.0.1/${sourceBrowsingRid.replace(
        "rad:",
modified tests/e2e/hashRouter.spec.ts
@@ -17,7 +17,7 @@ test("navigate between landing and project page", async ({ page }) => {
  await page.goto("/#/");
  await expect(page).toHaveURL("/#/");

-
  await page.locator("text=source-browsing").click();
+
  await page.getByText("source-browsing").click();
  await expect(page).toHaveURL(`/#${sourceBrowsingUrl}`);

  await expectBackAndForwardNavigationWorks("/#/", page);
@@ -34,7 +34,7 @@ test("navigation between seed and project pages", async ({ page }) => {
  await expectBackAndForwardNavigationWorks("/#/seeds/radicle.local", page);
  await expectUrlPersistsReload(page);

-
  await page.locator('role=link[name="radicle.local"]').click();
+
  await page.getByRole("link", { name: "radicle.local" }).click();
  await expect(page).toHaveURL("/#/seeds/127.0.0.1");
});

@@ -45,7 +45,7 @@ test.describe("project page navigation", () => {
    const projectHistoryURL = `/#${sourceBrowsingUrl}/history/${aliceMainHead}`;
    await page.goto(projectHistoryURL);

-
    await page.locator("text=Add README.md").click();
+
    await page.getByText("Add README.md").click();
    await expect(page).toHaveURL(
      `/#${sourceBrowsingUrl}/commits/${aliceMainHead}`,
    );
@@ -60,7 +60,7 @@ test.describe("project page navigation", () => {
    await page.goto(projectTreeURL);
    await expect(page).toHaveURL(projectTreeURL);

-
    await page.locator('role=link[name="6 commits"]').click();
+
    await page.getByRole("link", { name: "6 commits" }).click();
    await expect(page).toHaveURL(`/#${sourceBrowsingUrl}/history`);

    await expectBackAndForwardNavigationWorks(projectTreeURL, page);
@@ -73,11 +73,11 @@ test.describe("project page navigation", () => {
    await page.goto(projectTreeURL);
    await expect(page).toHaveURL(projectTreeURL);

-
    await page.locator("text=.hidden").click();
+
    await page.getByText(".hidden").click();
    await expect(page).toHaveURL(`${projectTreeURL}/tree/main/.hidden`);

-
    await page.locator("text=bin/").click();
-
    await page.locator("text=true").click();
+
    await page.getByText("bin/").click();
+
    await page.getByText("true").click();
    await expect(page).toHaveURL(`${projectTreeURL}/tree/main/bin/true`);

    await expectBackAndForwardNavigationWorks(
@@ -95,11 +95,11 @@ test.describe("project page navigation", () => {
    await page.goto(projectTreeURL);
    await expect(page).toHaveURL(projectTreeURL);

-
    await page.locator("text=.hidden").click();
+
    await page.getByText(".hidden").click();
    await expect(page).toHaveURL(`${projectTreeURL}/tree/main/.hidden`);

-
    await page.locator("text=bin/").click();
-
    await page.locator("text=true").click();
+
    await page.getByText("bin/").click();
+
    await page.getByText("true").click();
    await expect(page).toHaveURL(`${projectTreeURL}/tree/main/bin/true`);

    await expectBackAndForwardNavigationWorks(
modified tests/e2e/historyRouter.spec.ts
@@ -17,7 +17,7 @@ test("navigate between landing and project page", async ({ page }) => {
  await page.goto("/");
  await expect(page).toHaveURL("/");

-
  await page.locator("text=source-browsing").click();
+
  await page.getByText("source-browsing").click();
  await expect(page).toHaveURL(sourceBrowsingUrl);

  await expectBackAndForwardNavigationWorks("/", page);
@@ -34,7 +34,7 @@ test("navigation between seed and project pages", async ({ page }) => {
  await expectBackAndForwardNavigationWorks("/seeds/radicle.local", page);
  await expectUrlPersistsReload(page);

-
  await page.locator('role=link[name="radicle.local"]').click();
+
  await page.getByRole("link", { name: "radicle.local" }).click();
  await expect(page).toHaveURL("/seeds/127.0.0.1");
});

@@ -45,7 +45,7 @@ test.describe("project page navigation", () => {
    const projectHistoryURL = `${sourceBrowsingUrl}/history/${aliceMainHead}`;
    await page.goto(projectHistoryURL);

-
    await page.locator("text=Add README.md").click();
+
    await page.getByText("Add README.md").click();
    await expect(page).toHaveURL(
      `${sourceBrowsingUrl}/commits/${aliceMainHead}`,
    );
@@ -63,7 +63,7 @@ test.describe("project page navigation", () => {
      .waitFor({ state: "hidden" });
    await expect(page).toHaveURL(projectTreeURL);

-
    await page.locator('role=link[name="6 commits"]').click();
+
    await page.getByRole("link", { name: "6 commits" }).click();
    await expect(page).toHaveURL(
      `${sourceBrowsingUrl}/history/${aliceMainHead}`,
    );
@@ -78,11 +78,11 @@ test.describe("project page navigation", () => {
    await page.goto(projectTreeURL);
    await expect(page).toHaveURL(projectTreeURL);

-
    await page.locator("text=.hidden").click();
+
    await page.getByText(".hidden").click();
    await expect(page).toHaveURL(`${projectTreeURL}/.hidden`);

-
    await page.locator("text=bin/").click();
-
    await page.locator("text=true").click();
+
    await page.getByText("bin/").click();
+
    await page.getByText("true").click();
    await expect(page).toHaveURL(`${projectTreeURL}/bin/true`);

    await expectBackAndForwardNavigationWorks(
@@ -100,11 +100,11 @@ test.describe("project page navigation", () => {
    await page.goto(projectTreeURL);
    await expect(page).toHaveURL(projectTreeURL);

-
    await page.locator("text=.hidden").click();
+
    await page.getByText(".hidden").click();
    await expect(page).toHaveURL(`${projectTreeURL}/tree/main/.hidden`);

-
    await page.locator("text=bin/").click();
-
    await page.locator("text=true").click();
+
    await page.getByText("bin/").click();
+
    await page.getByText("true").click();
    await expect(page).toHaveURL(`${projectTreeURL}/tree/main/bin/true`);

    await expectBackAndForwardNavigationWorks(
modified tests/e2e/landingPage.spec.ts
@@ -13,19 +13,17 @@ test("show pinned projects", async ({ page }) => {
  await page.addInitScript(appConfigWithFixture);
  await page.goto("/");
  await expect(
-
    page.locator("text=Explore projects on the Radicle network."),
+
    page.getByText("Explore projects on the Radicle network."),
  ).toBeVisible();

  // Shows pinned project name.
-
  await expect(page.locator("text=source-browsing")).toBeVisible();
+
  await expect(page.getByText("source-browsing")).toBeVisible();
  //
  // Shows pinned project description.
  await expect(
-
    page.locator("text=Git repository for source browsing tests"),
+
    page.getByText("Git repository for source browsing tests"),
  ).toBeVisible();

  // Shows latest commit.
-
  await expect(
-
    page.locator(`text=${aliceMainHead.substring(0, 7)}`),
-
  ).toBeVisible();
+
  await expect(page.getByText(aliceMainHead.substring(0, 7))).toBeVisible();
});
modified tests/e2e/project.spec.ts
@@ -18,16 +18,14 @@ async function expectCounts(
  page: Page,
) {
  await expect(
-
    page.locator(
-
      `role=link[name="${params.commits} ${
-
        params.commits === 1 ? "commit" : "commits"
-
      }"]`,
-
    ),
+
    page.getByRole("link", {
+
      name: `${params.commits} ${params.commits === 1 ? "commit" : "commits"}`,
+
    }),
  ).toBeVisible();

  await expect(
-
    page.locator(
-
      `text=${params.contributors} ${
+
    page.getByText(
+
      `${params.contributors} ${
        params.contributors === 1 ? "contributor" : "contributors"
      }`,
    ),
@@ -39,10 +37,10 @@ test("navigate to project", async ({ page }) => {

  // Header.
  {
-
    const name = page.locator("text=source-browsing");
-
    const id = page.locator(`text=${sourceBrowsingRid}`);
-
    const description = page.locator(
-
      "text=Git repository for source browsing tests",
+
    const name = page.getByText("source-browsing");
+
    const id = page.getByText(sourceBrowsingRid);
+
    const description = page.getByText(
+
      "Git repository for source browsing tests",
    );

    await expect(name).toBeVisible();
@@ -62,18 +60,18 @@ test("navigate to project", async ({ page }) => {
  await expect(page.locator(".file-name")).toContainText("README.md");

  // Show a commit teaser.
-
  await expect(page.locator("text=dd068e9 Add README.md")).toBeVisible();
+
  await expect(page.getByText("dd068e9 Add README.md")).toBeVisible();

  // Show rendered README.md contents.
-
  await expect(page.locator("text=Git test repository")).toBeVisible();
+
  await expect(page.getByText("Git test repository")).toBeVisible();

  // Number of nodes tracking this project.
-
  await expect(page.locator("text=3 nodes")).toBeVisible();
+
  await expect(page.getByText("3 nodes")).toBeVisible();
});

test("show source tree at specific revision", async ({ page }) => {
  await page.goto(sourceBrowsingUrl);
-
  await page.locator('role=link[name="6 commits"]').click();
+
  await page.getByRole("link", { name: "6 commits" }).click();

  await page
    .locator(".teaser", { hasText: "335dd6d" })
@@ -137,7 +135,7 @@ test("navigate deep file hierarchies", async ({ page }) => {
  await sourceTree.getByText("repositories/").click();
  await sourceTree.getByText(".gitkeep").click();
  await expect(
-
    page.locator("text=0801ace Add a deeply nested directory tree"),
+
    page.getByText("0801ace Add a deeply nested directory tree"),
  ).toBeVisible();

  // After a page reload the tree browser is still expanded and we're still
@@ -159,7 +157,7 @@ test("navigate deep file hierarchies", async ({ page }) => {
    await expect(sourceTree.getByText(".gitkeep")).toBeVisible();

    await expect(
-
      page.locator("text=0801ace Add a deeply nested directory tree"),
+
      page.getByText("0801ace Add a deeply nested directory tree"),
    ).toBeVisible();
  }
});
@@ -213,7 +211,7 @@ test("binary files", async ({ page }) => {
  await page.getByText("bin/").click();
  await page.getByText("true").click();

-
  await expect(page.locator("text=Binary content")).toBeVisible();
+
  await expect(page.getByText("Binary content")).toBeVisible();
});

test("empty files", async ({ page }) => {
@@ -230,14 +228,14 @@ test("hidden files", async ({ page }) => {

  await page.getByText(".hidden").click();

-
  await expect(page.locator("text=I'm a hidden file.")).toBeVisible();
+
  await expect(page.getByText("I'm a hidden file.")).toBeVisible();
});

test("markdown files", async ({ page }) => {
  await page.goto(`${markdownUrl}/tree/main/cheatsheet.md`);

  await expect(
-
    page.locator("text=This is intended as a quick reference and showcase."),
+
    page.getByText("This is intended as a quick reference and showcase."),
  ).toBeVisible();

  // Switch between raw and rendered modes.
@@ -245,7 +243,7 @@ test("markdown files", async ({ page }) => {
    const toggleButton = page.getByTitle("Toggle render method");
    await expect(toggleButton).toHaveText("Plain");
    await toggleButton.click();
-
    await expect(page.locator("text=##### Table of Contents")).toBeVisible();
+
    await expect(page.getByText("##### Table of Contents")).toBeVisible();
    await expect(toggleButton).toHaveText("Markdown");
    await toggleButton.click();
  }
@@ -263,12 +261,10 @@ test("clone modal", async ({ page }) => {
  await page.goto(sourceBrowsingUrl);

  await page.getByText("Clone").click();
+
  await expect(page.getByText(`rad clone ${sourceBrowsingRid}`)).toBeVisible();
  await expect(
-
    page.locator(`text=rad clone ${sourceBrowsingRid}`),
-
  ).toBeVisible();
-
  await expect(
-
    page.locator(
-
      `text=http://127.0.0.1/${sourceBrowsingRid.replace("rad:", "")}.git`,
+
    page.getByText(
+
      `http://127.0.0.1/${sourceBrowsingRid.replace("rad:", "")}.git`,
    ),
  ).toBeVisible();
});
@@ -279,15 +275,15 @@ test("peer and branch switching", async ({ page }) => {
  // Alice's peer.
  {
    await page.getByTitle("Change peer").click();
-
    await page.locator(`text=${aliceRemote}`).click();
+
    await page.getByText(`${aliceRemote}`).click();
    await expect(page.getByTitle("Change peer")).toHaveText(
      `did:key:${aliceRemote.substring(8).substring(0, 6)}…${aliceRemote.slice(
        -6,
      )} (alice) delegate`,
    );
    await expect(
-
      page.locator(
-
        `text=source-browsing / did:key:${aliceRemote
+
      page.getByText(
+
        `source-browsing / did:key:${aliceRemote
          .substring(8)
          .substring(0, 6)}…${aliceRemote.slice(-6)}`,
      ),
@@ -304,7 +300,7 @@ test("peer and branch switching", async ({ page }) => {
    // Feature branch with a slash in the name.
    {
      await page.getByTitle("Change branch").click();
-
      await page.locator("text=feature/branch").click();
+
      await page.getByText("feature/branch").click();

      await expect(page.getByTitle("Current branch")).toContainText(
        "feature/branch 1aded56",
@@ -315,7 +311,7 @@ test("peer and branch switching", async ({ page }) => {
    // Branch without a history or files in it.
    {
      await page.getByTitle("Change branch").click();
-
      await page.locator("text=orphaned-branch").click();
+
      await page.getByText("orphaned-branch").click();

      await expect(page.getByTitle("Current branch")).toContainText(
        "orphaned-branch af3641c",
@@ -323,14 +319,14 @@ test("peer and branch switching", async ({ page }) => {
      await expectCounts({ commits: 1, contributors: 1 }, page);

      await expect(
-
        page.locator("text=We couldn't find any files at this revision."),
+
        page.getByText("We couldn't find any files at this revision."),
      ).toBeVisible();
    }
  }

  // Reset the source browser by clicking the project title.
  {
-
    await page.locator("text=source-browsing").click();
+
    await page.getByText("source-browsing").click();

    await expect(page.getByTitle("Change peer")).not.toContainText("alice");
    await expect(page.getByTitle("Change peer")).not.toContainText("bob");
@@ -338,13 +334,13 @@ test("peer and branch switching", async ({ page }) => {
    await expect(page.getByTitle("Current branch")).toContainText(
      `main ${aliceMainHead.substring(0, 7)}`,
    );
-
    await expect(page.locator("text=Git test repository")).toBeVisible();
+
    await expect(page.getByText("Git test repository")).toBeVisible();
  }

  // Bob's peer.
  {
    await page.getByTitle("Change peer").click();
-
    await page.locator(`text=${bobRemote}`).click();
+
    await page.getByText(bobRemote).click();
    await expect(page.getByTitle("Change peer")).toHaveText(
      `did:key:${bobRemote.substring(8).substring(0, 6)}…${bobRemote.slice(
        -6,
@@ -359,7 +355,7 @@ test("peer and branch switching", async ({ page }) => {
      );
      await expectCounts({ commits: 7, contributors: 2 }, page);
      await expect(
-
        page.locator(`text=${bobHead.substring(0, 7)} Update readme`),
+
        page.getByText(`${bobHead.substring(0, 7)} Update readme`),
      ).toBeVisible();
    }
  }
@@ -369,31 +365,31 @@ test("only one modal can be open at a time", async ({ page }) => {
  await page.goto(sourceBrowsingUrl);

  await page.getByTitle("Change peer").click();
-
  await page.locator(`text=${aliceRemote}`).click();
+
  await page.getByText(aliceRemote).click();

  await page.getByText("Clone").click();
-
  await expect(page.locator("text=Code font")).not.toBeVisible();
-
  await expect(page.locator("text=Use the Radicle CLI")).toBeVisible();
-
  await expect(page.locator("text=bob hyyzz9")).not.toBeVisible();
-
  await expect(page.locator("text=feature/branch")).not.toBeVisible();
+
  await expect(page.getByText("Code font")).not.toBeVisible();
+
  await expect(page.getByText("Use the Radicle CLI")).toBeVisible();
+
  await expect(page.getByText("bob hyyzz9")).not.toBeVisible();
+
  await expect(page.getByText("feature/branch")).not.toBeVisible();

-
  await page.locator('button[name="Settings"]').click();
-
  await expect(page.locator("text=Code font")).toBeVisible();
-
  await expect(page.locator("text=Use the Radicle CLI")).not.toBeVisible();
-
  await expect(page.locator("text=bob hyyzz9")).not.toBeVisible();
-
  await expect(page.locator("text=feature/branch")).not.toBeVisible();
+
  await page.getByRole("button", { name: "Settings" }).click();
+
  await expect(page.getByText("Code font")).toBeVisible();
+
  await expect(page.getByText("Use the Radicle CLI")).not.toBeVisible();
+
  await expect(page.getByText("bob hyyzz9")).not.toBeVisible();
+
  await expect(page.getByText("feature/branch")).not.toBeVisible();

  await page.getByTitle("Change branch").click();
-
  await expect(page.locator("text=Code font")).not.toBeVisible();
-
  await expect(page.locator("text=Use the Radicle CLI")).not.toBeVisible();
-
  await expect(page.locator("text=bob hyyzz9")).not.toBeVisible();
-
  await expect(page.locator("text=feature/branch")).toBeVisible();
+
  await expect(page.getByText("Code font")).not.toBeVisible();
+
  await expect(page.getByText("Use the Radicle CLI")).not.toBeVisible();
+
  await expect(page.getByText("bob hyyzz9")).not.toBeVisible();
+
  await expect(page.getByText("feature/branch")).toBeVisible();

  await page.getByTitle("Change peer").click();
-
  await expect(page.locator("text=Code font")).not.toBeVisible();
-
  await expect(page.locator("text=Use the Radicle CLI")).not.toBeVisible();
-
  await expect(page.locator(`text=${bobRemote}`)).toBeVisible();
-
  await expect(page.locator("text=feature/branch")).not.toBeVisible();
+
  await expect(page.getByText("Code font")).not.toBeVisible();
+
  await expect(page.getByText("Use the Radicle CLI")).not.toBeVisible();
+
  await expect(page.getByText(bobRemote)).toBeVisible();
+
  await expect(page.getByText("feature/branch")).not.toBeVisible();
});

test.describe("browser error handling", () => {
@@ -406,11 +402,9 @@ test.describe("browser error handling", () => {
    await page.goto(sourceBrowsingUrl);

    const sourceTree = page.locator(".source-tree");
-
    await sourceTree.locator("text=src/").click();
+
    await sourceTree.getByText("src/").click();

-
    await expect(
-
      page.locator("text=Not able to expand directory"),
-
    ).toBeVisible();
+
    await expect(page.getByText("Not able to expand directory")).toBeVisible();
  });
  test("error appears when file can't be loaded", async ({ page }) => {
    await page.route(
@@ -419,9 +413,9 @@ test.describe("browser error handling", () => {
    );

    await page.goto(sourceBrowsingUrl);
-
    await page.locator("text=.hidden").click();
+
    await page.getByText(".hidden").click();

-
    await expect(page.locator("text=Not able to load file")).toBeVisible();
+
    await expect(page.getByText("Not able to load file")).toBeVisible();
  });
  test("error appears when README can't be loaded", async ({ page }) => {
    await page.route(
@@ -431,7 +425,7 @@ test.describe("browser error handling", () => {

    await page.goto(sourceBrowsingUrl);
    await expect(
-
      page.locator("text=The README could not be loaded"),
+
      page.getByText("The README could not be loaded"),
    ).toBeVisible();
  });
  test("error appears when navigating to missing file", async ({ page }) => {
@@ -442,7 +436,7 @@ test.describe("browser error handling", () => {

    await page.goto(`${sourceBrowsingUrl}/tree/master/.hidden`);

-
    await expect(page.locator("text=Not able to load file")).toBeVisible();
+
    await expect(page.getByText("Not able to load file")).toBeVisible();
  });
});

modified tests/e2e/project/commit.spec.ts
@@ -12,10 +12,10 @@ const commitUrl = `${sourceBrowsingUrl}/commits/${bobHead}`;
test("navigation from commit list", async ({ page }) => {
  await page.goto(sourceBrowsingUrl);
  await page.getByTitle("Change peer").click();
-
  await page.locator(`text=${bobRemote}`).click();
-
  await page.locator('role=link[name="7 commits"]').click();
+
  await page.getByText(bobRemote).click();
+
  await page.getByRole("link", { name: "7 commits" }).click();

-
  await page.locator("text=Update readme").click();
+
  await page.getByText("Update readme").click();
  await expect(page).toHaveURL(commitUrl);
});

@@ -41,18 +41,18 @@ test("modified file", async ({ page }) => {
  // Commit header.
  {
    const header = page.locator(".commit .header");
-
    await expect(header.locator("text=Update readme")).toBeVisible();
-
    await expect(header.locator(`text=${bobHead}`)).toBeVisible();
+
    await expect(header.getByText("Update readme")).toBeVisible();
+
    await expect(header.getByText(bobHead)).toBeVisible();
  }

  // Diff header.
  await expect(
-
    page.locator("text=1 file changed with 1 insertion and 4 deletions"),
+
    page.getByText("1 file changed with 1 insertion and 4 deletions"),
  ).toBeVisible();

  // Diff.
-
  await expect(page.locator("text=-	# Git test repository")).toBeVisible();
-
  await expect(page.locator("text=+	Updated readme")).toBeVisible();
+
  await expect(page.getByText("-	# Git test repository")).toBeVisible();
+
  await expect(page.getByText("+	Updated readme")).toBeVisible();
});

test("created file", async ({ page }) => {
@@ -62,9 +62,9 @@ test("created file", async ({ page }) => {
    )}/commits/d87e27e38e244fb3346cb9e4df064c080d97647a`,
  );
  await expect(
-
    page.locator("text=1 file added with 1 insertion and 0 deletions"),
+
    page.getByText("1 file added with 1 insertion and 0 deletions"),
  ).toBeVisible();
-
  await expect(page.locator("text=.hidden added")).toBeVisible();
+
  await expect(page.getByText(".hidden added")).toBeVisible();
});

test("deleted file", async ({ page }) => {
@@ -74,9 +74,9 @@ test("deleted file", async ({ page }) => {
    )}/commits/0e2db54dfd47d87202809917e2342655d9e76296`,
  );
  await expect(
-
    page.locator("text=1 file deleted with 0 insertions and 1 deletion"),
+
    page.getByText("1 file deleted with 0 insertions and 1 deletion"),
  ).toBeVisible();
-
  await expect(page.locator("text=.hidden deleted")).toBeVisible();
+
  await expect(page.getByText(".hidden deleted")).toBeVisible();
});

test("moved file", async ({ page }) => {
@@ -98,7 +98,7 @@ test("navigation to source tree at specific revision", async ({ page }) => {
  // Go to source tree at this revision.
  await page.getByTitle("View file").click();
  await expect(
-
    page.locator("text=Add a deeply nested directory tree"),
+
    page.getByText("Add a deeply nested directory tree"),
  ).toBeVisible();
  await expect(page).toHaveURL(
    `${sourceBrowsingUrl}/tree/0801aceeab500033f8d608778218657bd626ef73/deep/directory/hierarchy/is/entirely/possible/in/git/repositories/.gitkeep`,
modified tests/e2e/project/issues.spec.ts
@@ -3,16 +3,16 @@ import { createProject } from "@tests/support/project";

test("navigate issue listing", async ({ page }) => {
  await page.goto(cobUrl);
-
  await page.locator('role=link[name="1 issue"]').click();
+
  await page.getByRole("link", { name: "1 issue" }).click();
  await expect(page).toHaveURL(`${cobUrl}/issues`);

-
  await page.locator('role=link[name="2 closed"]').click();
+
  await page.getByRole("link", { name: "2 closed" }).click();
  await expect(page).toHaveURL(`${cobUrl}/issues?state=closed`);
});

test("navigate single issue", async ({ page }) => {
  await page.goto(`${cobUrl}/issues`);
-
  await page.locator("text=This title has markdown").click();
+
  await page.getByText("This title has markdown").click();

  await expect(page).toHaveURL(
    `${cobUrl}/issues/4fc727e722d3979fd2073d9b56b2751658a4ae79`,
modified tests/e2e/project/patches.spec.ts
@@ -2,10 +2,10 @@ import { test, cobUrl, expect } from "@tests/support/fixtures.js";

test("navigate listing", async ({ page }) => {
  await page.goto(cobUrl);
-
  await page.locator('role=link[name="2 patches"]').click();
+
  await page.getByRole("link", { name: "2 patches" }).click();
  await expect(page).toHaveURL(`${cobUrl}/patches`);

-
  await page.locator('role=link[name="1 merged"]').click();
+
  await page.getByRole("link", { name: "1 merged" }).click();
  await expect(page).toHaveURL(`${cobUrl}/patches?state=merged`);
  await expect(
    page.locator(".comments").filter({ hasText: "5" }),
@@ -14,23 +14,23 @@ test("navigate listing", async ({ page }) => {

test("navigate patch details", async ({ page }) => {
  await page.goto(`${cobUrl}/patches`);
-
  await page.locator("text=Add subtitle to README").click();
+
  await page.getByText("Add subtitle to README").click();
  await expect(page).toHaveURL(
    `${cobUrl}/patches/013f8b2734df1840b2e33d52ff5632c8d66b199a`,
  );
-
  await page.locator("role=link[name='Add subtitle to README']").click();
+
  await page.getByRole("link", { name: "Add subtitle to README" }).click();
  await expect(page).toHaveURL(
    `${cobUrl}/commits/8c900d6cb38811e099efb3cbbdbfaba817bcf970`,
  );
  await page.goBack();
  {
-
    await page.locator("role=link[name='Commits']").click();
+
    await page.getByRole("link", { name: "Commits" }).click();
    await expect(page).toHaveURL(
      `${cobUrl}/patches/013f8b2734df1840b2e33d52ff5632c8d66b199a?tab=commits`,
    );
  }
  {
-
    await page.locator("role=link[name='Files']").click();
+
    await page.getByRole("link", { name: "Files" }).click();
    await expect(page).toHaveURL(
      `${cobUrl}/patches/013f8b2734df1840b2e33d52ff5632c8d66b199a?tab=files`,
    );
modified tests/e2e/seed.spec.ts
@@ -13,9 +13,9 @@ test("seed metadata", async ({ page }) => {
    page.locator(".header").getByText("radicle.local"),
  ).toBeVisible();
  await expect(
-
    page.locator(`text=${seedRemote.substring(0, 6)}…${seedRemote.slice(-6)}`),
+
    page.getByText(`${seedRemote.substring(0, 6)}…${seedRemote.slice(-6)}`),
  ).toBeVisible();
-
  await expect(page.locator(`text=0.1.0-`)).toBeVisible();
+
  await expect(page.getByText("0.1.0-")).toBeVisible();
});

test("seed projects", async ({ page }) => {
@@ -24,19 +24,17 @@ test("seed projects", async ({ page }) => {

  // Project metadata.
  {
-
    await expect(project.locator("text=source-browsing")).toBeVisible();
+
    await expect(project.getByText("source-browsing")).toBeVisible();
    await expect(
-
      project.locator("text=Git repository for source browsing tests"),
+
      project.getByText("Git repository for source browsing tests"),
    ).toBeVisible();
-
    await expect(project.locator(`text=${aliceMainHead}`)).toBeVisible();
+
    await expect(project.getByText(aliceMainHead)).toBeVisible();
  }

  // Show project ID on hover.
  {
-
    await expect(
-
      project.locator(`text=${sourceBrowsingRid}`),
-
    ).not.toBeVisible();
+
    await expect(project.getByText(sourceBrowsingRid)).not.toBeVisible();
    await project.hover();
-
    await expect(project.locator(`text=${sourceBrowsingRid}`)).toBeVisible();
+
    await expect(project.getByText(sourceBrowsingRid)).toBeVisible();
  }
});
modified tests/e2e/settings.spec.ts
@@ -17,7 +17,7 @@ test("default settings", async ({ page }) => {

test("settings persistance", async ({ page }) => {
  await page.goto(sourceBrowsingFixture);
-
  await page.locator('button[name="Settings"]').click();
+
  await page.getByRole("button", { name: "Settings" }).click();

  await page.locator(".theme .toggle").click();
  await page.getByText("Code font").click();
@@ -34,7 +34,7 @@ test("settings persistance", async ({ page }) => {

test("change theme", async ({ page }) => {
  await page.goto(sourceBrowsingFixture);
-
  await page.locator('button[name="Settings"]').click();
+
  await page.getByRole("button", { name: "Settings" }).click();

  await page.locator(".theme .toggle").click();
  await expect(page.locator("html")).toHaveAttribute("data-theme", "light");
@@ -58,7 +58,7 @@ test("change theme", async ({ page }) => {
test("change code font", async ({ page }) => {
  await page.goto(sourceBrowsingFixture);

-
  await page.locator('button[name="Settings"]').click();
+
  await page.getByRole("button", { name: "Settings" }).click();
  await page.getByText("Code font").click();

  await page.getByText("System").click();
modified tests/visual/markdown.spec.ts
@@ -25,7 +25,7 @@ test.describe("markdown rendering", async () => {
          waitUntil: "networkidle",
        },
      );
-
      await expect(page.locator("text=Table of Contents")).toBeVisible();
+
      await expect(page.getByText("Table of Contents")).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -36,7 +36,7 @@ test.describe("markdown rendering", async () => {
    });
    test("headers", async ({ page }) => {
      await goToSection("#headers", page);
-
      await expect(page.locator("text=###### H6")).toBeVisible();
+
      await expect(page.getByText("###### H6")).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -45,7 +45,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 470 } });
    test("emphasis", async ({ page }) => {
      await goToSection("#emphasis", page);
-
      await expect(page.locator("text=Emphasis, aka").first()).toBeVisible();
+
      await expect(page.getByText("Emphasis, aka").first()).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -54,9 +54,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 1100 } });
    test("lists", async ({ page }) => {
      await goToSection("#lists", page);
-
      await expect(
-
        page.locator("text=First ordered list").first(),
-
      ).toBeVisible();
+
      await expect(page.getByText("First ordered list").first()).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -65,7 +63,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 1024 } });
    test("links", async ({ page }) => {
      await goToSection("#links", page);
-
      await expect(page.locator("text=There are two ways")).toBeVisible();
+
      await expect(page.getByText("There are two ways")).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -74,7 +72,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 520 } });
    test("images", async ({ page }) => {
      await goToSection("#images", page);
-
      await expect(page.locator("text=Here's our logo").first()).toBeVisible();
+
      await expect(page.getByText("Here's our logo").first()).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -83,7 +81,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 1130 } });
    test("code and syntax highlighting", async ({ page }) => {
      await goToSection("#code", page);
-
      await expect(page.locator("text=Code blocks are part")).toBeVisible();
+
      await expect(page.getByText("Code blocks are part")).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -98,22 +96,18 @@ test.describe("markdown rendering", async () => {
          "text=This is an example footnote[0]. And some radicle[1] examples.",
        ),
      ).toBeVisible();
-
      await expect(page.locator("text=0. https://example.com ↩")).toBeVisible();
-
      await expect(page.locator("text=1. https://radicle.xyz ↩")).toBeVisible();
+
      await expect(page.getByText("0. https://example.com ↩")).toBeVisible();
+
      await expect(page.getByText("1. https://radicle.xyz ↩")).toBeVisible();
      await expect(page).toHaveScreenshot({ fullPage: true });

-
      await page.locator("text=Plain").click();
+
      await page.getByText("Plain").click();
      await expect(
        page.locator(
          "text=This is an example footnote[^0]. And some radicle[^1] examples.",
        ),
      ).toBeVisible();
-
      await expect(
-
        page.locator("text=[^0]: https://example.com"),
-
      ).toBeVisible();
-
      await expect(
-
        page.locator("text=[^1]: https://radicle.xyz"),
-
      ).toBeVisible();
+
      await expect(page.getByText("[^0]: https://example.com")).toBeVisible();
+
      await expect(page.getByText("[^1]: https://radicle.xyz")).toBeVisible();
    });
  });

@@ -133,9 +127,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 1100 } });
    test("tables", async ({ page }) => {
      await goToSection("#tables", page);
-
      await expect(
-
        page.locator("text=Tables aren't part of the"),
-
      ).toBeVisible();
+
      await expect(page.getByText("Tables aren't part of the")).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -144,7 +136,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 450 } });
    test("blockquotes", async ({ page }) => {
      await goToSection("#blockquotes", page);
-
      await expect(page.locator("text=Blockquotes are").first()).toBeVisible();
+
      await expect(page.getByText("Blockquotes are").first()).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -153,9 +145,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 510 } });
    test("inline HTML", async ({ page }) => {
      await goToSection("#html", page);
-
      await expect(
-
        page.locator("text=You can also use raw HTML"),
-
      ).toBeVisible();
+
      await expect(page.getByText("You can also use raw HTML")).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -164,7 +154,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 710 } });
    test("horizontal rule", async ({ page }) => {
      await goToSection("#hr", page);
-
      await expect(page.locator("text=Three or more...").first()).toBeVisible();
+
      await expect(page.getByText("Three or more...").first()).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -173,7 +163,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 625 } });
    test("line breaks", async ({ page }) => {
      await goToSection("#lines", page);
-
      await expect(page.locator("text=My basic recommendation")).toBeVisible();
+
      await expect(page.getByText("My basic recommendation")).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
@@ -182,7 +172,7 @@ test.describe("markdown rendering", async () => {
    test.use({ viewport: { width: viewportWidth, height: 500 } });
    test("videos", async ({ page }) => {
      await goToSection("#videos", page);
-
      await expect(page.locator("text=They can't be added")).toBeVisible();
+
      await expect(page.getByText("They can't be added")).toBeVisible();
      await expect(page).toHaveScreenshot();
    });
  });
modified tests/visual/mobile/project.spec.ts
@@ -50,6 +50,6 @@ test("commit page", async ({ page }) => {
      8,
    )}/commits/1aded56c3ad55299df9f06c326af50b802a05949`,
  );
-
  await expect(page.locator("text=subconscious.txt added")).toBeVisible();
+
  await expect(page.getByText("subconscious.txt added")).toBeVisible();
  await expect(page).toHaveScreenshot({ fullPage: true });
});
modified tests/visual/project.spec.ts
@@ -47,6 +47,6 @@ test("commit page", async ({ page }) => {
      8,
    )}/commits/1aded56c3ad55299df9f06c326af50b802a05949`,
  );
-
  await expect(page.locator("text=subconscious.txt added")).toBeVisible();
+
  await expect(page.getByText("subconscious.txt added")).toBeVisible();
  await expect(page).toHaveScreenshot({ fullPage: true });
});