mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-24 19:35:28 -06:00
fix(ui): correct Automations row semantics (#127252)
Amp-Thread-ID: https://ampcode.com/threads/T-01a021f4-b547-7788-a916-d4a94cbd3e3b Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
committed by
GitHub
parent
8531da1993
commit
7085604a26
@@ -63,7 +63,11 @@ suite.define(() => {
|
||||
expect(response?.status()).toBe(200);
|
||||
const row = page.locator(`[data-test-id="cron-row-${job.id}"]`);
|
||||
await row.waitFor({ state: "visible", timeout: 10_000 });
|
||||
await row.locator(".cron-table__name-text").click();
|
||||
expect(await page.locator(".cron-table__head").getAttribute("role")).toBeNull();
|
||||
expect(await row.getAttribute("role")).toBeNull();
|
||||
const openTask = row.getByRole("button", { name: /Nightly digest/ });
|
||||
await openTask.focus();
|
||||
await page.keyboard.press("Enter");
|
||||
const detail = page.locator('.cron-page[data-panel-mode="job"]');
|
||||
await detail.waitFor({ state: "visible" });
|
||||
|
||||
|
||||
@@ -116,7 +116,22 @@ describe("cron view list pane", () => {
|
||||
expect(onJobsFiltersReset).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("renders table rows with schedule and status cells and selects on click", () => {
|
||||
it("does not expose table rows without complete table semantics", () => {
|
||||
const container = renderView({ jobs: [createJob("job-1")] });
|
||||
|
||||
for (const row of container.querySelectorAll('[role="row"]')) {
|
||||
expect(row.closest('[role="table"], [role="grid"], [role="treegrid"]')).not.toBeNull();
|
||||
expect(
|
||||
Array.from(row.children).every((child) =>
|
||||
child.matches(
|
||||
'[role="cell"], [role="gridcell"], [role="columnheader"], [role="rowheader"]',
|
||||
),
|
||||
),
|
||||
).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("renders table rows with independent native buttons for opening tasks", () => {
|
||||
const onSelectJob = vi.fn();
|
||||
const job = createJob("job-1", {
|
||||
trigger: { script: "json({ fire: true })" },
|
||||
@@ -134,6 +149,7 @@ describe("cron view list pane", () => {
|
||||
|
||||
const rows = Array.from(container.querySelectorAll(".cron-table__row"));
|
||||
expect(rows).toHaveLength(3);
|
||||
expect(rows[0]?.getAttribute("role")).toBeNull();
|
||||
expect(rows[0]?.textContent).toContain("Cron 0 9 * * *");
|
||||
expect(rows[1]?.classList.contains("cron-table__row--paused")).toBe(true);
|
||||
expect(rows[1]?.textContent).toContain("Paused");
|
||||
@@ -150,7 +166,7 @@ describe("cron view list pane", () => {
|
||||
"Trigger configured",
|
||||
);
|
||||
|
||||
(rows[1] as HTMLElement).click();
|
||||
getElement(rows[1] as Element, ".cron-table__name", HTMLButtonElement).click();
|
||||
expect(onSelectJob).toHaveBeenCalledWith(paused);
|
||||
});
|
||||
|
||||
|
||||
@@ -728,7 +728,7 @@ function renderJobsFilterPopover(props: CronProps, active: boolean) {
|
||||
function renderJobsTable(props: CronProps, hasAnyJobsFilters: boolean) {
|
||||
return html`
|
||||
<div class="cron-table ${props.canManage ? "" : "cron-table--read-only"}">
|
||||
<div class="cron-table__head" role="row">
|
||||
<div class="cron-table__head">
|
||||
<span>${t("cron.jobs.name")}</span>
|
||||
<span>${t("cron.jobs.schedule")}</span>
|
||||
<span>${t("cron.jobs.nextRun")}</span>
|
||||
@@ -775,18 +775,10 @@ function renderJobRow(job: CronJob, props: CronProps) {
|
||||
return html`
|
||||
<div
|
||||
class="cron-table__row ${job.enabled ? "" : "cron-table__row--paused"}"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
data-test-id=${`cron-row-${job.id}`}
|
||||
@click=${() => props.onSelectJob(job)}
|
||||
@keydown=${(e: KeyboardEvent) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
props.onSelectJob(job);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span class="cron-table__name">
|
||||
<button type="button" class="cron-table__name">
|
||||
${renderJobStateIndicator(job)}
|
||||
<span class="cron-table__name-copy">
|
||||
<span class="cron-table__name-line">
|
||||
@@ -814,17 +806,13 @@ function renderJobRow(job: CronJob, props: CronProps) {
|
||||
`
|
||||
: nothing}
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
${renderJobCell("cron-table__schedule", t("cron.jobs.schedule"), formatCronSchedule(job))}
|
||||
${renderJobCell("cron-table__next", t("cron.jobs.nextRun"), nextRun)}
|
||||
${renderJobCell("cron-table__last", t("cron.jobs.lastRun"), renderLastRunCell(job))}
|
||||
${props.canManage
|
||||
? html`
|
||||
<span
|
||||
class="cron-table__actions"
|
||||
@click=${(e: Event) => e.stopPropagation()}
|
||||
@keydown=${(e: Event) => e.stopPropagation()}
|
||||
>
|
||||
<span class="cron-table__actions" @click=${(e: Event) => e.stopPropagation()}>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn--sm btn--ghost cron-row-run"
|
||||
|
||||
@@ -324,7 +324,7 @@
|
||||
}
|
||||
|
||||
.cron-table__row:hover,
|
||||
.cron-table__row:focus-visible {
|
||||
.cron-table__row:focus-within {
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
@@ -338,9 +338,13 @@
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
color: var(--text-strong);
|
||||
background: transparent;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.cron-table__state {
|
||||
|
||||
Reference in New Issue
Block a user