mirror of
https://seed.radicle.dev/rad:z4D5UCArafTzTQpDZNQRuqswh3ury.git
synced 2026-10-18 19:10:45 +08:00
Add tests for clipboard, issue listing and issues
This commit is contained in:
@@ -28,7 +28,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Playwright browsers
|
- name: Install Playwright browsers
|
||||||
if: steps.playwright-dep-cache.outputs.cache-hit != 'true'
|
if: steps.playwright-dep-cache.outputs.cache-hit != 'true'
|
||||||
run: npx playwright install webkit
|
run: npx playwright install webkit chromium
|
||||||
|
|
||||||
- name: Install Radicle binaries
|
- name: Install Radicle binaries
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -94,7 +94,7 @@
|
|||||||
</OutlineButton>
|
</OutlineButton>
|
||||||
<Popover popoverPositionRight="0" popoverPositionTop="3rem">
|
<Popover popoverPositionRight="0" popoverPositionTop="3rem">
|
||||||
{#snippet toggle(onclick)}
|
{#snippet toggle(onclick)}
|
||||||
<NakedButton variant="ghost" {onclick}>
|
<NakedButton title="Settings" variant="ghost" {onclick}>
|
||||||
<Icon name="settings" />
|
<Icon name="settings" />
|
||||||
</NakedButton>
|
</NakedButton>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { ComponentProps, Snippet } from "svelte";
|
import type { ComponentProps, Snippet } from "svelte";
|
||||||
|
|
||||||
import { debounce } from "lodash";
|
import { debounce } from "lodash";
|
||||||
import { writeText } from "@tauri-apps/plugin-clipboard-manager";
|
import { writeToClipboard } from "@app/lib/invoke";
|
||||||
|
|
||||||
import { formatOid } from "@app/lib/utils";
|
import { formatOid } from "@app/lib/utils";
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
async function copy() {
|
async function copy() {
|
||||||
await writeText(clipboard);
|
await writeToClipboard(clipboard);
|
||||||
icon = "checkmark";
|
icon = "checkmark";
|
||||||
tooltip = "Copied to clipboard";
|
tooltip = "Copied to clipboard";
|
||||||
restoreIcon();
|
restoreIcon();
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: Snippet;
|
children: Snippet;
|
||||||
|
title?: string;
|
||||||
variant: "primary" | "secondary" | "ghost";
|
variant: "primary" | "secondary" | "ghost";
|
||||||
onclick?: () => void;
|
onclick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { children, variant, onclick }: Props = $props();
|
const { children, title, variant, onclick }: Props = $props();
|
||||||
|
|
||||||
const style = $derived(
|
const style = $derived(
|
||||||
`--button-color-1: var(--color-fill-${variant});` +
|
`--button-color-1: var(--color-fill-${variant});` +
|
||||||
@@ -203,7 +204,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
<div class="container" {onclick} role="button" tabindex="0" {style}>
|
<div class="container" {onclick} {title} role="button" tabindex="0" {style}>
|
||||||
<div class="pixel p1-1"></div>
|
<div class="pixel p1-1"></div>
|
||||||
<div class="pixel p1-2"></div>
|
<div class="pixel p1-2"></div>
|
||||||
<div class="pixel p1-3"></div>
|
<div class="pixel p1-3"></div>
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<Id
|
<Id
|
||||||
|
ariaLabel="repo-id"
|
||||||
clipboard={repo.rid}
|
clipboard={repo.rid}
|
||||||
shorten={false}
|
shorten={false}
|
||||||
variant="oid"
|
variant="oid"
|
||||||
|
|||||||
@@ -19,3 +19,19 @@ export async function invoke<T = null>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function writeToClipboard(
|
||||||
|
text: string,
|
||||||
|
opts?: {
|
||||||
|
label?: string;
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
if (window.__TAURI_INTERNALS__) {
|
||||||
|
await tauri.invoke("plugin:clipboard-manager|write_text", {
|
||||||
|
label: opts?.label,
|
||||||
|
text,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await navigator.clipboard.writeText(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { chromium } from "playwright";
|
||||||
|
|
||||||
|
import { expect, markdownRid, test } from "@tests/support/fixtures.js";
|
||||||
|
|
||||||
|
// We explicitly run all clipboard tests withing the context of a single test
|
||||||
|
// so that we don't run into race conditions, because there is no way to isolate
|
||||||
|
// the clipboard in Playwright yet.
|
||||||
|
test("copy to clipboard", async () => {
|
||||||
|
const browser = await chromium.launch();
|
||||||
|
const context = await browser.newContext();
|
||||||
|
await context.grantPermissions(["clipboard-read", "clipboard-write"]);
|
||||||
|
const page = await context.newPage();
|
||||||
|
|
||||||
|
await page.goto("/repos");
|
||||||
|
|
||||||
|
// Reset system clipboard to a known state.
|
||||||
|
await page.evaluate<string>("navigator.clipboard.writeText('')");
|
||||||
|
|
||||||
|
// Repo ID.
|
||||||
|
{
|
||||||
|
await page.getByLabel("repo-id").first().click();
|
||||||
|
const clipboardContent = await page.evaluate<string>(
|
||||||
|
"navigator.clipboard.readText()",
|
||||||
|
);
|
||||||
|
expect(clipboardContent).toBe(markdownRid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the system clipboard contents so developers don't wonder why there's
|
||||||
|
// random stuff in their clipboard after running tests.
|
||||||
|
await page.evaluate<string>("navigator.clipboard.writeText('')");
|
||||||
|
});
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { test, expect, cobRid } from "@tests/support/fixtures.js";
|
||||||
|
|
||||||
|
test("navigate single issue", async ({ page }) => {
|
||||||
|
await page.goto(`/repos/${cobRid}/issues?status=all`);
|
||||||
|
await page.getByText("This title has **markdown**").click();
|
||||||
|
|
||||||
|
await expect(page).toHaveURL(/\/issues\/[0-9a-f]{40}/);
|
||||||
|
});
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { test, cobRid, expect } from "@tests/support/fixtures.js";
|
||||||
|
|
||||||
|
test("navigate issues listing", async ({ page }) => {
|
||||||
|
await page.goto(`/repos/${cobRid}/issues?show=all`);
|
||||||
|
await expect(page.locator(".issue-teaser")).toHaveCount(3);
|
||||||
|
|
||||||
|
await page.getByRole("link", { name: "Closed" }).click();
|
||||||
|
await expect(page.locator(".issue-teaser")).toHaveCount(2);
|
||||||
|
await expect(page).toHaveURL(`/repos/${cobRid}/issues?status=closed`);
|
||||||
|
});
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { test, expect } from "@tests/support/fixtures.js";
|
||||||
|
|
||||||
|
test("default theme", async ({ page }) => {
|
||||||
|
await page.goto("/repos");
|
||||||
|
|
||||||
|
await expect(page.locator("html")).toHaveAttribute("data-theme", "dark");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("theme persistence", async ({ page }) => {
|
||||||
|
await page.goto("/repos");
|
||||||
|
await expect(page.getByRole("button", { name: "markdown" })).toBeVisible();
|
||||||
|
await page.getByRole("button", { name: "Settings" }).click();
|
||||||
|
|
||||||
|
await page.getByRole("button", { name: "Light", exact: true }).click();
|
||||||
|
await expect(page.locator("html")).toHaveAttribute("data-theme", "light");
|
||||||
|
|
||||||
|
await page.reload();
|
||||||
|
|
||||||
|
await expect(page.locator("html")).toHaveAttribute("data-theme", "light");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("change theme", async ({ page }) => {
|
||||||
|
await page.goto("/repos");
|
||||||
|
await expect(page.getByRole("button", { name: "markdown" })).toBeVisible();
|
||||||
|
await page.getByRole("button", { name: "Settings" }).click();
|
||||||
|
|
||||||
|
await page.getByRole("button", { name: "Light", exact: true }).click();
|
||||||
|
await expect(page.locator("html")).toHaveAttribute("data-theme", "light");
|
||||||
|
|
||||||
|
await page.getByRole("button", { name: "Dark", exact: true }).click();
|
||||||
|
await expect(page.locator("html")).toHaveAttribute("data-theme", "dark");
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user