Skip to content

Commit 001f165

Browse files
committed
e2e: Add Playwright tests for trustpub_only checkbox and warning banner
Port the QUnit tests to Playwright for the trustpub_only feature: - Warning banner visibility tests (5 tests) - Checkbox visibility and interaction tests (8 tests)
1 parent cb560e8 commit 001f165

File tree

1 file changed

+224
-1
lines changed

1 file changed

+224
-1
lines changed

e2e/routes/crate/settings.spec.ts

Lines changed: 224 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test } from '@/e2e/helper';
2-
import { click } from '@ember/test-helpers';
2+
import { defer } from '@/e2e/deferred';
33
import { http, HttpResponse } from 'msw';
44

55
test.describe('Route | crate.settings', { tag: '@routes' }, () => {
@@ -277,5 +277,228 @@ test.describe('Route | crate.settings', { tag: '@routes' }, () => {
277277
);
278278
});
279279
});
280+
281+
test.describe('trustpub_only warning banner', () => {
282+
test('hidden when flag is false', async ({ msw, page }) => {
283+
await prepare(msw);
284+
285+
await page.goto('/crates/foo/settings');
286+
287+
await expect(page.locator('[data-test-trustpub-only-warning]')).not.toBeVisible();
288+
});
289+
290+
test('hidden when flag is true and configs exist', async ({ msw, page }) => {
291+
const { crate } = await prepare(msw);
292+
msw.db.crate.update({ where: { id: { equals: crate.id } }, data: { trustpubOnly: true } });
293+
294+
msw.db.trustpubGithubConfig.create({
295+
crate,
296+
repository_owner: 'rust-lang',
297+
repository_name: 'crates.io',
298+
workflow_filename: 'ci.yml',
299+
});
300+
301+
await page.goto('/crates/foo/settings');
302+
303+
await expect(page.locator('[data-test-trustpub-only-warning]')).not.toBeVisible();
304+
});
305+
306+
test('shown when flag is true but no configs exist', async ({ msw, page, percy }) => {
307+
const { crate } = await prepare(msw);
308+
msw.db.crate.update({ where: { id: { equals: crate.id } }, data: { trustpubOnly: true } });
309+
310+
await page.goto('/crates/foo/settings');
311+
312+
await expect(page.locator('[data-test-trustpub-only-warning]')).toBeVisible();
313+
await expect(page.locator('[data-test-trustpub-only-warning]')).toHaveText(
314+
'Trusted publishing is required but no publishers are configured. Publishing to this crate is currently blocked.',
315+
);
316+
317+
await percy.snapshot();
318+
});
319+
320+
test('disappears when checkbox is unchecked', async ({ msw, page }) => {
321+
const { crate } = await prepare(msw);
322+
msw.db.crate.update({ where: { id: { equals: crate.id } }, data: { trustpubOnly: true } });
323+
324+
await page.goto('/crates/foo/settings');
325+
326+
await expect(page.locator('[data-test-trustpub-only-warning]')).toBeVisible();
327+
328+
await page.click('[data-test-trustpub-only-checkbox] [data-test-checkbox]');
329+
330+
await expect(page.locator('[data-test-trustpub-only-warning]')).not.toBeVisible();
331+
});
332+
333+
test('appears when last config is removed', async ({ msw, page }) => {
334+
const { crate } = await prepare(msw);
335+
msw.db.crate.update({ where: { id: { equals: crate.id } }, data: { trustpubOnly: true } });
336+
337+
msw.db.trustpubGithubConfig.create({
338+
crate,
339+
repository_owner: 'rust-lang',
340+
repository_name: 'crates.io',
341+
workflow_filename: 'ci.yml',
342+
});
343+
344+
await page.goto('/crates/foo/settings');
345+
346+
await expect(page.locator('[data-test-trustpub-only-warning]')).not.toBeVisible();
347+
348+
await page.click('[data-test-github-config="1"] [data-test-remove-config-button]');
349+
350+
await expect(page.locator('[data-test-trustpub-only-warning]')).toBeVisible();
351+
});
352+
});
353+
354+
test.describe('trustpub_only checkbox', () => {
355+
test('hidden when no configs and flag is false', async ({ msw, page }) => {
356+
await prepare(msw);
357+
358+
await page.goto('/crates/foo/settings');
359+
360+
await expect(page.locator('[data-test-trustpub-only-checkbox]')).not.toBeVisible();
361+
});
362+
363+
test('visible when GitHub configs exist', async ({ msw, page }) => {
364+
const { crate } = await prepare(msw);
365+
366+
msw.db.trustpubGithubConfig.create({
367+
crate,
368+
repository_owner: 'rust-lang',
369+
repository_name: 'crates.io',
370+
workflow_filename: 'ci.yml',
371+
});
372+
373+
await page.goto('/crates/foo/settings');
374+
375+
await expect(page.locator('[data-test-trustpub-only-checkbox]')).toBeVisible();
376+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).not.toBeChecked();
377+
});
378+
379+
test('visible when GitLab configs exist', async ({ msw, page }) => {
380+
const { crate } = await prepare(msw);
381+
382+
msw.db.trustpubGitlabConfig.create({
383+
crate,
384+
namespace: 'rust-lang',
385+
project: 'crates.io',
386+
workflow_filepath: '.gitlab-ci.yml',
387+
});
388+
389+
await page.goto('/crates/foo/settings');
390+
391+
await expect(page.locator('[data-test-trustpub-only-checkbox]')).toBeVisible();
392+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).not.toBeChecked();
393+
});
394+
395+
test('visible when flag is true but no configs', async ({ msw, page }) => {
396+
const { crate } = await prepare(msw);
397+
msw.db.crate.update({ where: { id: { equals: crate.id } }, data: { trustpubOnly: true } });
398+
399+
await page.goto('/crates/foo/settings');
400+
401+
await expect(page.locator('[data-test-trustpub-only-checkbox]')).toBeVisible();
402+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).toBeChecked();
403+
});
404+
405+
test('stays visible after disabling when no configs exist', async ({ msw, page }) => {
406+
const { crate } = await prepare(msw);
407+
msw.db.crate.update({ where: { id: { equals: crate.id } }, data: { trustpubOnly: true } });
408+
409+
await page.goto('/crates/foo/settings');
410+
411+
await expect(page.locator('[data-test-trustpub-only-checkbox]')).toBeVisible();
412+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).toBeChecked();
413+
414+
await page.click('[data-test-trustpub-only-checkbox] [data-test-checkbox]');
415+
416+
// Checkbox stays visible after disabling (within same page visit)
417+
await expect(page.locator('[data-test-trustpub-only-checkbox]')).toBeVisible();
418+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).not.toBeChecked();
419+
420+
// After navigating away and back, checkbox should be hidden
421+
await page.goto('/crates/foo');
422+
await page.goto('/crates/foo/settings');
423+
424+
await expect(page.locator('[data-test-trustpub-only-checkbox]')).not.toBeVisible();
425+
});
426+
427+
test('enabling trustpub_only', async ({ msw, page }) => {
428+
const { crate } = await prepare(msw);
429+
430+
msw.db.trustpubGithubConfig.create({
431+
crate,
432+
repository_owner: 'rust-lang',
433+
repository_name: 'crates.io',
434+
workflow_filename: 'ci.yml',
435+
});
436+
437+
await page.goto('/crates/foo/settings');
438+
439+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).not.toBeChecked();
440+
expect(msw.db.crate.findFirst({ where: { name: { equals: crate.name } } })?.trustpubOnly).toBe(false);
441+
442+
await page.click('[data-test-trustpub-only-checkbox] [data-test-checkbox]');
443+
444+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).toBeChecked();
445+
expect(msw.db.crate.findFirst({ where: { name: { equals: crate.name } } })?.trustpubOnly).toBe(true);
446+
});
447+
448+
test('disabling trustpub_only', async ({ msw, page }) => {
449+
const { crate } = await prepare(msw);
450+
msw.db.crate.update({ where: { id: { equals: crate.id } }, data: { trustpubOnly: true } });
451+
452+
msw.db.trustpubGithubConfig.create({
453+
crate,
454+
repository_owner: 'rust-lang',
455+
repository_name: 'crates.io',
456+
workflow_filename: 'ci.yml',
457+
});
458+
459+
await page.goto('/crates/foo/settings');
460+
461+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).toBeChecked();
462+
expect(msw.db.crate.findFirst({ where: { name: { equals: crate.name } } })?.trustpubOnly).toBe(true);
463+
464+
await page.click('[data-test-trustpub-only-checkbox] [data-test-checkbox]');
465+
466+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).not.toBeChecked();
467+
expect(msw.db.crate.findFirst({ where: { name: { equals: crate.name } } })?.trustpubOnly).toBe(false);
468+
});
469+
470+
test('loading and error state', async ({ msw, page }) => {
471+
const { crate } = await prepare(msw);
472+
473+
msw.db.trustpubGithubConfig.create({
474+
crate,
475+
repository_owner: 'rust-lang',
476+
repository_name: 'crates.io',
477+
workflow_filename: 'ci.yml',
478+
});
479+
480+
let deferred = defer();
481+
msw.worker.use(http.patch('/api/v1/crates/:name', () => deferred.promise));
482+
483+
await page.goto('/crates/foo/settings');
484+
485+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).toBeVisible();
486+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-spinner]')).not.toBeVisible();
487+
488+
await page.click('[data-test-trustpub-only-checkbox] [data-test-checkbox]');
489+
490+
// Check loading state
491+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-spinner]')).toBeVisible();
492+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).not.toBeVisible();
493+
494+
// Resolve with error
495+
deferred.resolve(HttpResponse.json({ errors: [{ detail: 'Server error' }] }, { status: 500 }));
496+
497+
// Check that spinner is gone and checkbox is back
498+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-checkbox]')).toBeVisible();
499+
await expect(page.locator('[data-test-trustpub-only-checkbox] [data-test-spinner]')).not.toBeVisible();
500+
await expect(page.locator('[data-test-notification-message]')).toHaveText('Server error');
501+
});
502+
});
280503
});
281504
});

0 commit comments

Comments
 (0)