|
| 1 | +import {test as base, chromium} from '@playwright/test' |
| 2 | + |
| 3 | +/** |
| 4 | + * @typedef {import('@playwright/test').BrowserContext} BrowserContext |
| 5 | + */ |
| 6 | +const extensionFixtures = ( |
| 7 | + /** @type {string} */ pathToExtension, |
| 8 | + /** @type {boolean} */ headless |
| 9 | + /** @returns {import('@playwright/test').TestModifier<{}, {context: BrowserContext, extensionId: string}>} */ |
| 10 | +) => { |
| 11 | + return base.extend({ |
| 12 | + /** @type {() => Promise<BrowserContext>} */ |
| 13 | + // eslint-disable-next-line no-empty-pattern |
| 14 | + context: async ({}, use) => { |
| 15 | + const context = await chromium.launchPersistentContext('', { |
| 16 | + headless: false, |
| 17 | + args: [ |
| 18 | + headless ? `--headless=new` : '', |
| 19 | + `--disable-extensions-except=${pathToExtension}`, |
| 20 | + `--load-extension=${pathToExtension}`, |
| 21 | + '--no-first-run', // Disable Chrome's native first run experience. |
| 22 | + '--disable-client-side-phishing-detection', // Disables client-side phishing detection |
| 23 | + '--disable-component-extensions-with-background-pages', // Disable some built-in extensions that aren't affected by '--disable-extensions' |
| 24 | + '--disable-default-apps', // Disable installation of default apps |
| 25 | + '--disable-features=InterestFeedContentSuggestions', // Disables the Discover feed on NTP |
| 26 | + '--disable-features=Translate', // Disables Chrome translation, both the manual option and the popup prompt when a page with differing language is detected. |
| 27 | + '--hide-scrollbars', // Hide scrollbars from screenshots. |
| 28 | + '--mute-audio', // Mute any audio |
| 29 | + '--no-default-browser-check', // Disable the default browser check, do not prompt to set it as such |
| 30 | + '--no-first-run', // Skip first run wizards |
| 31 | + '--ash-no-nudges', // Avoids blue bubble "user education" nudges (eg., "… give your browser a new look", Memory Saver) |
| 32 | + '--disable-search-engine-choice-screen', // Disable the 2023+ search engine choice screen |
| 33 | + '--disable-features=MediaRoute', // Avoid the startup dialog for `Do you want the application “Chromium.app” to accept incoming network connections?`. Also disables the Chrome Media Router which creates background networking activity to discover cast targets. A superset of disabling DialMediaRouteProvider. |
| 34 | + '--use-mock-keychain', // Use mock keychain on Mac to prevent the blocking permissions dialog about "Chrome wants to use your confidential information stored in your keychain" |
| 35 | + '--disable-background-networking', // Disable various background network services, including extension updating, safe browsing service, upgrade detector, translate, UMA |
| 36 | + '--disable-breakpad', // Disable crashdump collection (reporting is already disabled in Chromium) |
| 37 | + '--disable-component-update', // Don't update the browser 'components' listed at chrome://components/ |
| 38 | + '--disable-domain-reliability', // Disables Domain Reliability Monitoring, which tracks whether the browser has difficulty contacting Google-owned sites and uploads reports to Google. |
| 39 | + '--disable-features=AutofillServerCommunicatio', // Disables autofill server communication. This feature isn't disabled via other 'parent' flags. |
| 40 | + '--disable-features=CertificateTransparencyComponentUpdate', |
| 41 | + '--disable-sync', // Disable syncing to a Google account |
| 42 | + '--disable-features=OptimizationHints', // Used for turning on Breakpad crash reporting in a debug environment where crash reporting is typically compiled but disabled. Disable the Chrome Optimization Guide and networking with its service API |
| 43 | + '--disable-features=DialMediaRouteProvider', // A weaker form of disabling the MediaRouter feature. See that flag's details. |
| 44 | + '--no-pings', // Don't send hyperlink auditing pings |
| 45 | + '--enable-features=SidePanelUpdates' // Ensure the side panel is visible. This is used for testing the side panel feature. |
| 46 | + ].filter((arg) => !!arg) |
| 47 | + }) |
| 48 | + await use(context) |
| 49 | + await context.close() |
| 50 | + }, |
| 51 | + /** @type {() => Promise<string>} */ |
| 52 | + extensionId: async ({context}, use) => { |
| 53 | + /* |
| 54 | + // for manifest v2: |
| 55 | + let [background] = context.backgroundPages() |
| 56 | + if (!background) |
| 57 | + background = await context.waitForEvent('backgroundpage') |
| 58 | + */ |
| 59 | + |
| 60 | + // for manifest v3: |
| 61 | + let [background] = context.serviceWorkers() |
| 62 | + if (!background) background = await context.waitForEvent('serviceworker') |
| 63 | + |
| 64 | + const extensionId = background.url().split('/')[2] |
| 65 | + await use(extensionId) |
| 66 | + } |
| 67 | + }) |
| 68 | +} |
| 69 | + |
| 70 | +export {extensionFixtures} |
0 commit comments