|
| 1 | +import { readdir, readFile } from 'node:fs/promises'; |
| 2 | +import { basename, join } from 'node:path'; |
1 | 3 | import { test, expect, type Page } from '@playwright/test'; |
2 | 4 |
|
3 | 5 | /** |
@@ -39,6 +41,109 @@ test.describe('Widget Loading', () => { |
39 | 41 | const button = page.locator('#bugdrop-host').locator('css=.bd-trigger'); |
40 | 42 | await expect(button).toBeVisible(); |
41 | 43 | }); |
| 44 | + |
| 45 | + test('missing local test config returns an empty script', async ({ page }) => { |
| 46 | + const response = await page.request.get('/test/local-config.js'); |
| 47 | + |
| 48 | + expect(response.status()).toBe(200); |
| 49 | + expect(response.headers()['content-type']).toContain('application/javascript'); |
| 50 | + expect(await response.text()).toBe(''); |
| 51 | + }); |
| 52 | + |
| 53 | + test('test pages use upstream repo when no local override is present', async ({ page }) => { |
| 54 | + await page.route('**/test/local-config.js', route => { |
| 55 | + return route.fulfill({ status: 404 }); |
| 56 | + }); |
| 57 | + |
| 58 | + await page.goto('/test/'); |
| 59 | + |
| 60 | + const widgetScript = page.locator('script[src="/widget.js"]'); |
| 61 | + await expect(widgetScript).toBeAttached(); |
| 62 | + |
| 63 | + const repo = await widgetScript.evaluate(script => { |
| 64 | + return (script as HTMLScriptElement).dataset.repo; |
| 65 | + }); |
| 66 | + |
| 67 | + expect(repo).toBe('mean-weasel/bugdrop-widget-test'); |
| 68 | + }); |
| 69 | + |
| 70 | + test('test pages use local repo override when configured', async ({ page }) => { |
| 71 | + await page.route('**/test/local-config.js', route => { |
| 72 | + return route.fulfill({ |
| 73 | + contentType: 'application/javascript', |
| 74 | + body: ` |
| 75 | + window.BugDropTestConfig = { |
| 76 | + ...(window.BugDropTestConfig || {}), |
| 77 | + repo: 'local-owner/local-repo', |
| 78 | + }; |
| 79 | + `, |
| 80 | + }); |
| 81 | + }); |
| 82 | + |
| 83 | + await page.goto('/test/'); |
| 84 | + |
| 85 | + const widgetScript = page.locator('script[src="/widget.js"]'); |
| 86 | + await expect(widgetScript).toBeAttached(); |
| 87 | + |
| 88 | + const repo = await widgetScript.evaluate(script => { |
| 89 | + return (script as HTMLScriptElement).dataset.repo; |
| 90 | + }); |
| 91 | + |
| 92 | + expect(repo).toBe('local-owner/local-repo'); |
| 93 | + }); |
| 94 | + |
| 95 | + test('non-index test pages use local repo override when configured', async ({ page }) => { |
| 96 | + await page.route('**/test/local-config.js', route => { |
| 97 | + return route.fulfill({ |
| 98 | + contentType: 'application/javascript', |
| 99 | + body: ` |
| 100 | + window.BugDropTestConfig = { |
| 101 | + ...(window.BugDropTestConfig || {}), |
| 102 | + repo: 'local-owner/local-repo', |
| 103 | + }; |
| 104 | + `, |
| 105 | + }); |
| 106 | + }); |
| 107 | + |
| 108 | + await page.goto('/test/color-default.html'); |
| 109 | + |
| 110 | + const widgetScript = page.locator('script[src="/widget.js"]'); |
| 111 | + await expect(widgetScript).toBeAttached(); |
| 112 | + |
| 113 | + const repo = await widgetScript.evaluate(script => { |
| 114 | + return (script as HTMLScriptElement).dataset.repo; |
| 115 | + }); |
| 116 | + |
| 117 | + expect(repo).toBe('local-owner/local-repo'); |
| 118 | + }); |
| 119 | + |
| 120 | + test('widget test fixtures use shared local config loader', async () => { |
| 121 | + const fixtureDir = join(process.cwd(), 'public', 'test'); |
| 122 | + const fixtureNames = (await readdir(fixtureDir)).filter(name => name.endsWith('.html')); |
| 123 | + const nonWidgetFixtures = new Set(['pull-tab-mock.html']); |
| 124 | + |
| 125 | + for (const fixtureName of fixtureNames) { |
| 126 | + const source = await readFile(join(fixtureDir, fixtureName), 'utf8'); |
| 127 | + const directWidgetScript = /<script\b(?=[^>]*\bsrc=["']\/widget\.js["'])/i.test(source); |
| 128 | + |
| 129 | + expect( |
| 130 | + directWidgetScript, |
| 131 | + `${fixtureName} should load the widget through load-widget.js` |
| 132 | + ).toBe(false); |
| 133 | + expect(source, `${fixtureName} should not hard-code the upstream test repo`).not.toContain( |
| 134 | + 'data-repo="mean-weasel/bugdrop-widget-test"' |
| 135 | + ); |
| 136 | + |
| 137 | + if (!nonWidgetFixtures.has(basename(fixtureName))) { |
| 138 | + expect(source, `${fixtureName} should include the shared test loader`).toContain( |
| 139 | + 'src="/test/load-widget.js"' |
| 140 | + ); |
| 141 | + expect(source, `${fixtureName} should call the shared test loader`).toContain( |
| 142 | + 'loadBugDropTestWidget' |
| 143 | + ); |
| 144 | + } |
| 145 | + } |
| 146 | + }); |
42 | 147 | }); |
43 | 148 |
|
44 | 149 | test.describe('Widget Interaction', () => { |
|
0 commit comments