diff --git a/e2e/playwright/projects.spec.ts b/e2e/playwright/projects.spec.ts index cab24566d..3b69e8fe0 100644 --- a/e2e/playwright/projects.spec.ts +++ b/e2e/playwright/projects.spec.ts @@ -297,13 +297,12 @@ test( const pointOnModel = { x: 630, y: 280 } - await test.step('Opening the bracket project should load the stream', async () => { // expect to see the text bracket await expect(page.getByText('bracket')).toBeVisible() await page.getByText('bracket').click() - + await expect( page.getByRole('button', { name: 'Start Sketch' }) ).toBeEnabled({ diff --git a/e2e/playwright/sketch-tests.spec.ts b/e2e/playwright/sketch-tests.spec.ts index 1d439782c..22e2b8fc4 100644 --- a/e2e/playwright/sketch-tests.spec.ts +++ b/e2e/playwright/sketch-tests.spec.ts @@ -388,7 +388,7 @@ test.describe('Sketch tests', () => { const dragPX = 40 await page - .getByText('circle({ center: [4.61, -5.01], radius: 8 }, %)') + .getByText('circle({ center = [4.61, -5.01], radius = 8 }, %)') .click() await expect( page.getByRole('button', { name: 'Edit Sketch' }) diff --git a/e2e/playwright/test-utils.ts b/e2e/playwright/test-utils.ts index e94687961..25ab69d03 100644 --- a/e2e/playwright/test-utils.ts +++ b/e2e/playwright/test-utils.ts @@ -30,103 +30,126 @@ import { reportRejection } from 'lib/trap' // The below is copied from playwright-core because it exports none of them :( import { Env, BrowserContextOptions } from 'playwright-core' -import type * as channels from '@protocol/channels'; +import type * as channels from '@protocol/channels' // Copied from playwright-core -function envObjectToArray(env: Env): { name: string, value: string }[] { - const result: { name: string, value: string }[] = []; +function envObjectToArray(env: Env): { name: string; value: string }[] { + const result: { name: string; value: string }[] = [] for (const name in env) { if (!Object.is(env[name], undefined)) - result.push({ name, value: String(env[name]) }); + result.push({ name, value: String(env[name]) }) } - return result; + return result } // Copied from playwright-core -export async function toClientCertificatesProtocol(certs?: BrowserContextOptions['clientCertificates']): Promise { - if (!certs) - return undefined; +export async function toClientCertificatesProtocol( + certs?: BrowserContextOptions['clientCertificates'] +): Promise { + if (!certs) return undefined - const bufferizeContent = async (value?: Buffer, path?: string): Promise => { - if (value) - return value; - if (path) - return await fs.promises.readFile(path); - }; + const bufferizeContent = async ( + value?: Buffer, + path?: string + ): Promise => { + if (value) return value + if (path) return await fs.promises.readFile(path) + } - return await Promise.all(certs.map(async cert => ({ - origin: cert.origin, - cert: await bufferizeContent(cert.cert, cert.certPath), - key: await bufferizeContent(cert.key, cert.keyPath), - pfx: await bufferizeContent(cert.pfx, cert.pfxPath), - passphrase: cert.passphrase, - }))); + return await Promise.all( + certs.map(async (cert) => ({ + origin: cert.origin, + cert: await bufferizeContent(cert.cert, cert.certPath), + key: await bufferizeContent(cert.key, cert.keyPath), + pfx: await bufferizeContent(cert.pfx, cert.pfxPath), + passphrase: cert.passphrase, + })) + ) } // Copied from playwright-core function toAcceptDownloadsProtocol(acceptDownloads?: boolean) { - if (acceptDownloads === undefined) - return undefined; - if (acceptDownloads) - return 'accept'; - return 'deny'; + if (acceptDownloads === undefined) return undefined + if (acceptDownloads) return 'accept' + return 'deny' } // Copied from playwright-core -function prepareRecordHarOptions(options: BrowserContextOptions['recordHar']): channels.RecordHarOptions | undefined { - if (!options) - return; +function prepareRecordHarOptions( + options: BrowserContextOptions['recordHar'] +): channels.RecordHarOptions | undefined { + if (!options) return return { path: options.path, content: options.content || (options.omitContent ? 'omit' : undefined), urlGlob: isString(options.urlFilter) ? options.urlFilter : undefined, - urlRegexSource: isRegExp(options.urlFilter) ? options.urlFilter.source : undefined, - urlRegexFlags: isRegExp(options.urlFilter) ? options.urlFilter.flags : undefined, - mode: options.mode - }; -} - -// Copied from playwright-core -async function prepareStorageState(options: BrowserContextOptions): Promise { - if (typeof options.storageState !== 'string') - return options.storageState; - try { - return JSON.parse(await fs.promises.readFile(options.storageState, 'utf8')); - } catch (e) { - rewriteErrorMessage(e, `Error reading storage state from ${options.storageState}:\n` + e.message); - throw e; + urlRegexSource: isRegExp(options.urlFilter) + ? options.urlFilter.source + : undefined, + urlRegexFlags: isRegExp(options.urlFilter) + ? options.urlFilter.flags + : undefined, + mode: options.mode, } } // Copied from playwright-core -async function prepareBrowserContextParams(options: BrowserContextOptions): Promise { +async function prepareStorageState( + options: BrowserContextOptions +): Promise { + if (typeof options.storageState !== 'string') return options.storageState + try { + return JSON.parse(await fs.promises.readFile(options.storageState, 'utf8')) + } catch (e) { + rewriteErrorMessage( + e, + `Error reading storage state from ${options.storageState}:\n` + e.message + ) + throw e + } +} + +// Copied from playwright-core +async function prepareBrowserContextParams( + options: BrowserContextOptions +): Promise { if (options.videoSize && !options.videosPath) - throw new Error(`"videoSize" option requires "videosPath" to be specified`); + throw new Error(`"videoSize" option requires "videosPath" to be specified`) if (options.extraHTTPHeaders) - network.validateHeaders(options.extraHTTPHeaders); + network.validateHeaders(options.extraHTTPHeaders) const contextParams: channels.BrowserNewContextParams = { ...options, viewport: options.viewport === null ? undefined : options.viewport, noDefaultViewport: options.viewport === null, - extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined, + extraHTTPHeaders: options.extraHTTPHeaders + ? headersObjectToArray(options.extraHTTPHeaders) + : undefined, storageState: await prepareStorageState(options), serviceWorkers: options.serviceWorkers, recordHar: prepareRecordHarOptions(options.recordHar), - colorScheme: options.colorScheme === null ? 'no-override' : options.colorScheme, - reducedMotion: options.reducedMotion === null ? 'no-override' : options.reducedMotion, - forcedColors: options.forcedColors === null ? 'no-override' : options.forcedColors, + colorScheme: + options.colorScheme === null ? 'no-override' : options.colorScheme, + reducedMotion: + options.reducedMotion === null ? 'no-override' : options.reducedMotion, + forcedColors: + options.forcedColors === null ? 'no-override' : options.forcedColors, acceptDownloads: toAcceptDownloadsProtocol(options.acceptDownloads), - clientCertificates: await toClientCertificatesProtocol(options.clientCertificates), - }; + clientCertificates: await toClientCertificatesProtocol( + options.clientCertificates + ), + } if (!contextParams.recordVideo && options.videosPath) { contextParams.recordVideo = { dir: options.videosPath, - size: options.videoSize - }; + size: options.videoSize, + } } if (contextParams.recordVideo && contextParams.recordVideo.dir) - contextParams.recordVideo.dir = path.resolve(process.cwd(), contextParams.recordVideo.dir); - return contextParams; + contextParams.recordVideo.dir = path.resolve( + process.cwd(), + contextParams.recordVideo.dir + ) + return contextParams } const toNormalizedCode = (text: string) => { @@ -973,7 +996,10 @@ export async function setup( localStorage.clear() localStorage.setItem('TOKEN_PERSIST_KEY', token) localStorage.setItem('persistCode', ``) - localStorage.setItem(PERSIST_MODELING_CONTEXT, JSON.stringify({openPanes: ['code']})) + localStorage.setItem( + PERSIST_MODELING_CONTEXT, + JSON.stringify({ openPanes: ['code'] }) + ) localStorage.setItem(settingsKey, settings) localStorage.setItem(IS_PLAYWRIGHT_KEY, 'true') localStorage.setItem('PLAYWRIGHT_TEST_DIR', PLAYWRIGHT_TEST_DIR) diff --git a/e2e/playwright/testing-segment-overlays.spec.ts b/e2e/playwright/testing-segment-overlays.spec.ts index 782b3a6fd..4bc6168b6 100644 --- a/e2e/playwright/testing-segment-overlays.spec.ts +++ b/e2e/playwright/testing-segment-overlays.spec.ts @@ -95,7 +95,9 @@ test.describe('Testing segment overlays', () => { }) .click() await expect(page.locator('.cm-content')).toContainText(expectFinal) - await editor.expectEditor.toContain(expectFinal, { shouldNormalise: true }) + await editor.expectEditor.toContain(expectFinal, { + shouldNormalise: true, + }) await editor.expectEditor.toContain(expectFinal, { shouldNormalise: true, }) diff --git a/e2e/playwright/zoo-test.ts b/e2e/playwright/zoo-test.ts index 591e1f5bf..2470a2db2 100644 --- a/e2e/playwright/zoo-test.ts +++ b/e2e/playwright/zoo-test.ts @@ -223,15 +223,15 @@ export const test = ( if (tronApp instanceof AuthenticatedTronApp) { tronApp.context.folderSetupFn = async function (fn) { return fn(tronApp.dir) - .then(() => tronApp.page.reload()) - .then(() => ({ - dir: tronApp.dir, - })) + .then(() => tronApp.page.reload()) + .then(() => ({ + dir: tronApp.dir, + })) } } if (!firstUrl) { - await tronApp.page.getByText('Your Projects').count(); + await tronApp.page.getByText('Your Projects').count() firstUrl = tronApp.page.url() } @@ -243,7 +243,7 @@ export const test = ( // }); await tronApp.electronApp.evaluate(({ app }, projectDirName) => { - console.log("ABCDEFGHI", app.testProperty['TEST_SETTINGS_FILE_KEY']) + console.log('ABCDEFGHI', app.testProperty['TEST_SETTINGS_FILE_KEY']) app.testProperty['TEST_SETTINGS_FILE_KEY'] = projectDirName }, tronApp.dir) diff --git a/package.json b/package.json index 174b37a2a..90646d067 100644 --- a/package.json +++ b/package.json @@ -152,7 +152,7 @@ "@iarna/toml": "^2.2.5", "@lezer/generator": "^1.7.1", "@nabla/vite-plugin-eslint": "^2.0.5", - "@playwright/test": "^1.46.1", + "@playwright/test": "^1.49.0", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^15.0.2", "@types/d3-force": "^3.0.10", diff --git a/src/lib/desktop.ts b/src/lib/desktop.ts index 0d3cd5544..0525655e5 100644 --- a/src/lib/desktop.ts +++ b/src/lib/desktop.ts @@ -391,7 +391,9 @@ const getAppFolderName = () => { export const getAppSettingsFilePath = async () => { const isTestEnv = window.electron.process.env.IS_PLAYWRIGHT === 'true' - const testSettingsPath = await window.electron.getAppTestProperty('TEST_SETTINGS_FILE_KEY') + const testSettingsPath = await window.electron.getAppTestProperty( + 'TEST_SETTINGS_FILE_KEY' + ) const appConfig = await window.electron.getPath('appData') const fullPath = isTestEnv ? testSettingsPath @@ -408,7 +410,9 @@ export const getAppSettingsFilePath = async () => { } const getTokenFilePath = async () => { const isTestEnv = window.electron.process.env.IS_PLAYWRIGHT === 'true' - const testSettingsPath = await window.electron.getAppTestProperty('TEST_SETTINGS_FILE_KEY') + const testSettingsPath = await window.electron.getAppTestProperty( + 'TEST_SETTINGS_FILE_KEY' + ) const appConfig = await window.electron.getPath('appData') const fullPath = isTestEnv ? testSettingsPath diff --git a/src/lib/exportSave.ts b/src/lib/exportSave.ts index 912de324f..54394e4f3 100644 --- a/src/lib/exportSave.ts +++ b/src/lib/exportSave.ts @@ -18,7 +18,9 @@ const save_ = async (file: ModelingAppFile, toastId: string) => { if (window.electron.process.env.IS_PLAYWRIGHT) { // Skip file picker, save to the test dir downloads directory - const testSettingsPath = await window.electron.getAppTestProperty('TEST_SETTINGS_FILE_KEY') + const testSettingsPath = await window.electron.getAppTestProperty( + 'TEST_SETTINGS_FILE_KEY' + ) const downloadDir = window.electron.join( testSettingsPath, 'downloads-during-playwright' diff --git a/src/main.ts b/src/main.ts index eb8e1c8be..d4dd41953 100644 --- a/src/main.ts +++ b/src/main.ts @@ -62,22 +62,26 @@ if (process.defaultApp) { registerStartupListeners() const createWindow = (filePath?: string, reuse?: boolean): BrowserWindow => { - const newWindow = reuse ? mainWindow : new BrowserWindow({ - autoHideMenuBar: true, - show: false, - width: 1800, - height: 1200, - webPreferences: { - nodeIntegration: false, // do not give the application implicit system access - contextIsolation: true, // expose system functions in preload - sandbox: false, // expose nodejs in preload - preload: path.join(__dirname, './preload.js'), - }, - icon: path.resolve(process.cwd(), 'assets', 'icon.png'), - frame: os.platform() !== 'darwin', - titleBarStyle: 'hiddenInset', - backgroundColor: nativeTheme.shouldUseDarkColors ? '#1C1C1C' : '#FCFCFC', - }) + const newWindow = reuse + ? mainWindow + : new BrowserWindow({ + autoHideMenuBar: true, + show: false, + width: 1800, + height: 1200, + webPreferences: { + nodeIntegration: false, // do not give the application implicit system access + contextIsolation: true, // expose system functions in preload + sandbox: false, // expose nodejs in preload + preload: path.join(__dirname, './preload.js'), + }, + icon: path.resolve(process.cwd(), 'assets', 'icon.png'), + frame: os.platform() !== 'darwin', + titleBarStyle: 'hiddenInset', + backgroundColor: nativeTheme.shouldUseDarkColors + ? '#1C1C1C' + : '#FCFCFC', + }) // and load the index.html of the app. if (MAIN_WINDOW_VITE_DEV_SERVER_URL) { diff --git a/src/preload.ts b/src/preload.ts index f999de820..a9e5b1cc9 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -31,7 +31,8 @@ const onUpdateDownloadStart = ( const onUpdateError = (callback: (value: Error) => void) => ipcRenderer.on('update-error', (_event: any, value) => callback(value)) const appRestart = () => ipcRenderer.invoke('app.restart') -const getAppTestProperty = (propertyName: string) => ipcRenderer.invoke('app.testProperty', propertyName) +const getAppTestProperty = (propertyName: string) => + ipcRenderer.invoke('app.testProperty', propertyName) const isMac = os.platform() === 'darwin' const isWindows = os.platform() === 'win32' diff --git a/yarn.lock b/yarn.lock index 82b619785..1a24d4220 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2131,12 +2131,12 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@playwright/test@^1.46.1": - version "1.46.1" - resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.46.1.tgz#a8dfdcd623c4c23bb1b7ea588058aad41055c188" - integrity sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA== +"@playwright/test@^1.49.0": + version "1.49.1" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.49.1.tgz#55fa360658b3187bfb6371e2f8a64f50ef80c827" + integrity sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g== dependencies: - playwright "1.46.1" + playwright "1.49.1" "@react-hook/latest@^1.0.2": version "1.0.3" @@ -7506,17 +7506,17 @@ pkg-types@^1.0.3, pkg-types@^1.1.1: mlly "^1.7.1" pathe "^1.1.2" -playwright-core@1.46.1: - version "1.46.1" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.46.1.tgz#28f3ab35312135dda75b0c92a3e5c0e7edb9cc8b" - integrity sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A== +playwright-core@1.49.1: + version "1.49.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.49.1.tgz#32c62f046e950f586ff9e35ed490a424f2248015" + integrity sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg== -playwright@1.46.1: - version "1.46.1" - resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.46.1.tgz#ea562bc48373648e10420a10c16842f0b227c218" - integrity sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng== +playwright@1.49.1: + version "1.49.1" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.49.1.tgz#830266dbca3008022afa7b4783565db9944ded7c" + integrity sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA== dependencies: - playwright-core "1.46.1" + playwright-core "1.49.1" optionalDependencies: fsevents "2.3.2" @@ -8533,16 +8533,7 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8636,14 +8627,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -9500,16 +9484,7 @@ word-wrap@^1.2.5: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==