diff --git a/eslint.config.js b/eslint.config.js index e0742192..d48911d4 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,13 +1,13 @@ -import config from '@lvce-editor/eslint-config' +import * as config from '@lvce-editor/eslint-config' export default [ - ...config, + ...config.default, + ...config.recommendedRegex, + ...config.recommendedActions, { files: ['packages/e2e/**/*.ts'], rules: { '@cspell/spellchecker': 'off', - '@typescript-eslint/no-unnecessary-type-assertion': 'off', - '@typescript-eslint/prefer-readonly-parameter-types': 'off', }, }, ] diff --git a/package-lock.json b/package-lock.json index 18951f3e..b1124d53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -710,9 +710,9 @@ } }, "node_modules/@emnapi/core": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", - "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", "dev": true, "license": "MIT", "dependencies": { @@ -721,9 +721,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", - "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", "dev": true, "license": "MIT", "dependencies": { @@ -808,9 +808,9 @@ } }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -3188,9 +3188,9 @@ } }, "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", - "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -4086,7 +4086,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz", "integrity": "sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A==", - "deprecated": "Deprecated and no longer maintained. Please use conventional-changelog instead.", "dev": true, "license": "MIT", "dependencies": { @@ -5443,9 +5442,9 @@ } }, "node_modules/eslint-plugin-sonarjs/node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -5638,9 +5637,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -6167,9 +6166,9 @@ } }, "node_modules/front-matter/node_modules/js-yaml": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", - "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -6188,9 +6187,9 @@ "license": "MIT" }, "node_modules/fs-extra": { - "version": "11.3.6", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.6.tgz", - "integrity": "sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", + "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", "dev": true, "license": "MIT", "dependencies": { @@ -6437,7 +6436,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", - "deprecated": "Deprecated and no longer maintained. Use @conventional-changelog/git-client instead.", + "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.", "dev": true, "license": "MIT", "dependencies": { @@ -6480,7 +6479,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz", "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==", - "deprecated": "Deprecated and no longer maintained. Use @conventional-changelog/git-client instead.", + "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.", "dev": true, "license": "MIT", "dependencies": { @@ -7497,9 +7496,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", - "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", "dev": true, "funding": [ { @@ -9832,9 +9831,9 @@ } }, "node_modules/module-replacements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-3.0.0.tgz", - "integrity": "sha512-tHIZqde+RlyNRobAIjfcH5UIgIrEbZbDGRL6J/x+HERX/g8O9mrm0p6knJbsTXmQtDvZ+eFP+xfOP3/9jHk6YA==", + "version": "3.0.0-beta.8", + "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-3.0.0-beta.8.tgz", + "integrity": "sha512-sc8TepP9elxoOBXEpxmhPzKKjTjbswHVcmsKGbgvm3k6jZlLu/WMV/Lfmga6IGMgHU/V3WtY2s6VEgM4nTElUQ==", "dev": true, "license": "MIT" }, @@ -10888,9 +10887,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { diff --git a/packages/diff-view/src/parts/GetErrorStackDom/GetStackLinePrefix/GetStackLinePrefix.ts b/packages/diff-view/src/parts/GetErrorStackDom/GetStackLinePrefix/GetStackLinePrefix.ts index ed13c298..1777edb6 100644 --- a/packages/diff-view/src/parts/GetErrorStackDom/GetStackLinePrefix/GetStackLinePrefix.ts +++ b/packages/diff-view/src/parts/GetErrorStackDom/GetStackLinePrefix/GetStackLinePrefix.ts @@ -1,9 +1,11 @@ import { parseStackLocation } from '../StackLocationRegex/StackLocationRegex.ts' +const trailingOpenParenthesisRegex = /\($/ + export const getStackLinePrefix = (stackLine: string): string => { const match = parseStackLocation(stackLine) if (!match) { return stackLine } - return stackLine.slice(0, stackLine.length - match.text.length).replace(/\($/, '') + return stackLine.slice(0, stackLine.length - match.text.length).replace(trailingOpenParenthesisRegex, '') } diff --git a/packages/diff-view/src/parts/GetErrorStackDom/StackLocationRegex/StackLocationRegex.ts b/packages/diff-view/src/parts/GetErrorStackDom/StackLocationRegex/StackLocationRegex.ts index 1dbafc9c..ea26c8d1 100644 --- a/packages/diff-view/src/parts/GetErrorStackDom/StackLocationRegex/StackLocationRegex.ts +++ b/packages/diff-view/src/parts/GetErrorStackDom/StackLocationRegex/StackLocationRegex.ts @@ -3,6 +3,8 @@ export interface StackLocationMatch { readonly text: string } +const whitespaceRegex = /\s/ + const isSchemeCharacter = (char: string): boolean => { return (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9') || char === '+' || char === '.' || char === '-' } @@ -12,7 +14,7 @@ const isSchemeStart = (char: string): boolean => { } const isLocationBoundary = (stackLine: string, index: number): boolean => { - return index === 0 || stackLine[index - 1] === '(' || /\s/.test(stackLine[index - 1]) + return index === 0 || stackLine[index - 1] === '(' || whitespaceRegex.test(stackLine[index - 1]) } const getSchemeLocationStart = (stackLine: string, locationEnd: number): number => { diff --git a/packages/diff-view/src/parts/GetSyntaxLanguage/GetSyntaxLanguage.ts b/packages/diff-view/src/parts/GetSyntaxLanguage/GetSyntaxLanguage.ts index d21f9ec7..fea8d0ef 100644 --- a/packages/diff-view/src/parts/GetSyntaxLanguage/GetSyntaxLanguage.ts +++ b/packages/diff-view/src/parts/GetSyntaxLanguage/GetSyntaxLanguage.ts @@ -13,9 +13,11 @@ export interface SyntaxLanguageInfo { readonly tokenizerPath: string } +const queryOrHashRegex = /[?#]/ + const getFileName = (uri: string): string => { const protocol = getProtocol(uri) - const path = getPath(protocol, uri).split(/[?#]/, 1)[0] + const path = getPath(protocol, uri).split(queryOrHashRegex, 1)[0] const lastSlashIndex = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')) if (lastSlashIndex === -1) { return path diff --git a/packages/diff-view/test/GetContentRightDom.test.ts b/packages/diff-view/test/GetContentRightDom.test.ts index e706710b..5f822ec5 100644 --- a/packages/diff-view/test/GetContentRightDom.test.ts +++ b/packages/diff-view/test/GetContentRightDom.test.ts @@ -7,7 +7,7 @@ import { getContentRightDom } from '../src/parts/GetContentRightDom/GetContentRi import * as InputName from '../src/parts/InputName/InputName.ts' import { VisibleLineType } from '../src/parts/VisibleLine/VisibleLine.ts' -test.skip('getContentRightDom renders each right line inside an EditorRow', (): void => { +test('getContentRightDom renders each right line inside an EditorRow', (): void => { const result = getContentRightDom({ allowedLinkSchemes: defaultAllowedLinkSchemes, contentRight: 'after-content\nsecond-line', @@ -61,7 +61,7 @@ test.skip('getContentRightDom renders each right line inside an EditorRow', (): ]) }) -test.skip('getContentRightDom renders cursor for editable right content', (): void => { +test('getContentRightDom renders cursor for editable right content', (): void => { const result = getContentRightDom({ allowedLinkSchemes: defaultAllowedLinkSchemes, contentRight: 'after-content', @@ -128,13 +128,15 @@ test.skip('getContentRightDom renders cursor for editable right content', (): vo className: ClassNames.DiffEditorInput, name: InputName.DiffEditorInput, onInput: DomEventListenerFunctions.HandleInput, - type: VirtualDomElements.Input, + selectionEnd: 0, + selectionStart: 0, + type: VirtualDomElements.TextArea, value: '', }, ]) }) -test.skip('getContentRightDom renders load errors when available', (): void => { +test('getContentRightDom renders load errors when available', (): void => { const result = getContentRightDom({ contentRight: '', errorMessage: 'permission denied', @@ -156,7 +158,7 @@ test.skip('getContentRightDom renders load errors when available', (): void => { ]) }) -test.skip('getContentRightDom renders paired deletion and insertion on the same row', (): void => { +test('getContentRightDom renders paired deletion and insertion on the same row', (): void => { const result = getContentRightDom({ allowedLinkSchemes: defaultAllowedLinkSchemes, contentRight: 'shared-line\nadded-line', @@ -215,7 +217,7 @@ test.skip('getContentRightDom renders paired deletion and insertion on the same ]) }) -test.skip('getContentRightDom renders syntax-highlighted token spans', (): void => { +test('getContentRightDom renders syntax-highlighted token spans', (): void => { const result = getContentRightDom({ allowedLinkSchemes: defaultAllowedLinkSchemes, contentRight: 'const answer = 1', diff --git a/packages/e2e/src/diff.media-fallback-missing-invalid.ts b/packages/e2e/src/diff.media-fallback-missing-invalid.ts index 3c3d53bc..fa442693 100644 --- a/packages/e2e/src/diff.media-fallback-missing-invalid.ts +++ b/packages/e2e/src/diff.media-fallback-missing-invalid.ts @@ -4,6 +4,8 @@ export const name = 'diff.media-fallback-missing-invalid' export const skip = 1 +const svgDataUriRegex = /^data:image\/svg\+xml;/ + export const test: Test = async ({ DiffView, expect, FileSystem, Locator, Workspace }) => { const tmpDir = await FileSystem.getTmpDir() await Workspace.setPath(tmpDir) @@ -15,7 +17,7 @@ export const test: Test = async ({ DiffView, expect, FileSystem, Locator, Worksp const afterPane = Locator('.DiffPane--after') const afterImage = Locator('.DiffPane--after .ImageElement') await expect(beforePane).toContainText('Failed to load image') - await expect(afterImage).toHaveAttribute('src', /^data:image\/svg\+xml;/ as unknown as string) + await expect(afterImage).toHaveAttribute('src', svgDataUriRegex as unknown as string) await FileSystem.writeFile(`${tmpDir}/left-invalid.mp4`, 'not a video') await DiffView.open(`${tmpDir}/left-invalid.mp4`, `${tmpDir}/missing-right.mp4`) diff --git a/packages/e2e/src/diff.video-different-formats-valid-both.ts b/packages/e2e/src/diff.video-different-formats-valid-both.ts index ac9768ed..4108b9b7 100644 --- a/packages/e2e/src/diff.video-different-formats-valid-both.ts +++ b/packages/e2e/src/diff.video-different-formats-valid-both.ts @@ -4,6 +4,9 @@ export const name = 'diff.video-different-formats-valid-both' export const skip = 1 +const mp4DataUriRegex = /^data:video\/mp4;base64,/ +const webmDataUriRegex = /^data:video\/webm;base64,/ + export const test: Test = async ({ DiffView, expect, FileSystem, Locator }) => { const tmpDir = await FileSystem.getTmpDir() await FileSystem.writeFile(`${tmpDir}/left.mp4`, 'fixture') @@ -15,7 +18,7 @@ export const test: Test = async ({ DiffView, expect, FileSystem, Locator }) => { const afterVideo = Locator('.DiffPane--after .VideoElement') await expect(beforeVideo).toHaveAttribute('title', 'left.mp4') - await expect(beforeVideo).toHaveAttribute('src', /^data:video\/mp4;base64,/ as unknown as string) + await expect(beforeVideo).toHaveAttribute('src', mp4DataUriRegex as unknown as string) await expect(afterVideo).toHaveAttribute('title', 'right.webm') - await expect(afterVideo).toHaveAttribute('src', /^data:video\/webm;base64,/ as unknown as string) + await expect(afterVideo).toHaveAttribute('src', webmDataUriRegex as unknown as string) } diff --git a/packages/e2e/src/diff.video-invalid-left-valid-right.ts b/packages/e2e/src/diff.video-invalid-left-valid-right.ts index c903a9ec..56192f5e 100644 --- a/packages/e2e/src/diff.video-invalid-left-valid-right.ts +++ b/packages/e2e/src/diff.video-invalid-left-valid-right.ts @@ -4,6 +4,8 @@ export const name = 'diff.video-invalid-left-valid-right' export const skip = 1 +const mp4DataUriRegex = /^data:video\/mp4;base64,/ + export const test: Test = async ({ DiffView, expect, FileSystem, Locator }) => { const tmpDir = await FileSystem.getTmpDir() await FileSystem.writeFile(`${tmpDir}/left-invalid.mp4`, 'fixture') @@ -16,5 +18,5 @@ export const test: Test = async ({ DiffView, expect, FileSystem, Locator }) => { await expect(beforePane).toContainText('Failed to load video: left-invalid.mp4') await expect(afterVideo).toHaveAttribute('title', 'right-valid.mp4') - await expect(afterVideo).toHaveAttribute('src', /^data:video\/mp4;base64,/ as unknown as string) + await expect(afterVideo).toHaveAttribute('src', mp4DataUriRegex as unknown as string) } diff --git a/packages/e2e/src/diff.video-mp4-valid-both.ts b/packages/e2e/src/diff.video-mp4-valid-both.ts index b74b4a43..f1ccf858 100644 --- a/packages/e2e/src/diff.video-mp4-valid-both.ts +++ b/packages/e2e/src/diff.video-mp4-valid-both.ts @@ -4,6 +4,8 @@ export const name = 'diff.video-mp4-valid-both' export const skip = 1 +const mp4DataUriRegex = /^data:video\/mp4;base64,/ + export const test: Test = async ({ DiffView, expect, FileSystem, Locator }) => { const tmpDir = await FileSystem.getTmpDir() await FileSystem.writeFile(`${tmpDir}/left.mp4`, 'fixture') @@ -15,7 +17,7 @@ export const test: Test = async ({ DiffView, expect, FileSystem, Locator }) => { const afterVideo = Locator('.DiffPane--after .VideoElement') await expect(beforeVideo).toHaveAttribute('title', 'left.mp4') - await expect(beforeVideo).toHaveAttribute('src', /^data:video\/mp4;base64,/ as unknown as string) + await expect(beforeVideo).toHaveAttribute('src', mp4DataUriRegex as unknown as string) await expect(afterVideo).toHaveAttribute('title', 'right.mp4') - await expect(afterVideo).toHaveAttribute('src', /^data:video\/mp4;base64,/ as unknown as string) + await expect(afterVideo).toHaveAttribute('src', mp4DataUriRegex as unknown as string) } diff --git a/packages/e2e/src/diff.video-text-left-video-right.ts b/packages/e2e/src/diff.video-text-left-video-right.ts index 03da3608..ff5b48cb 100644 --- a/packages/e2e/src/diff.video-text-left-video-right.ts +++ b/packages/e2e/src/diff.video-text-left-video-right.ts @@ -4,6 +4,8 @@ export const name = 'diff.video-text-left-video-right' export const skip = 1 +const mp4DataUriRegex = /^data:video\/mp4;base64,/ + export const test: Test = async ({ DiffView, expect, FileSystem, Locator }) => { const tmpDir = await FileSystem.getTmpDir() await FileSystem.writeFile(`${tmpDir}/left.txt`, 'fixture') @@ -16,5 +18,5 @@ export const test: Test = async ({ DiffView, expect, FileSystem, Locator }) => { await expect(beforePane).toContainText('const leftValue = 42') await expect(afterVideo).toHaveAttribute('title', 'right.mp4') - await expect(afterVideo).toHaveAttribute('src', /^data:video\/mp4;base64,/ as unknown as string) + await expect(afterVideo).toHaveAttribute('src', mp4DataUriRegex as unknown as string) }