Skip to content

Commit

Permalink
test: reduce optimize-deps playground flaky fail (#15205)
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red authored Dec 2, 2023
1 parent 7fd7c6c commit 4380b82
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 53 deletions.
147 changes: 94 additions & 53 deletions playground/optimize-deps/__tests__/optimize-deps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { describe, expect, test } from 'vitest'
import {
browserErrors,
browserLogs,
expectWithRetry,
getColor,
isBuild,
isServe,
Expand All @@ -12,93 +13,123 @@ import {
} from '~utils'

test('default + named imports from cjs dep (react)', async () => {
expect(await page.textContent('.cjs button')).toBe('count is 0')
await expectWithRetry(() => page.textContent('.cjs button')).toBe(
'count is 0',
)
await page.click('.cjs button')
expect(await page.textContent('.cjs button')).toBe('count is 1')
await expectWithRetry(() => page.textContent('.cjs button')).toBe(
'count is 1',
)
})

test('named imports from webpacked cjs (phoenix)', async () => {
expect(await page.textContent('.cjs-phoenix')).toBe('ok')
await expectWithRetry(() => page.textContent('.cjs-phoenix')).toBe('ok')
})

test('default import from webpacked cjs (clipboard)', async () => {
expect(await page.textContent('.cjs-clipboard')).toBe('ok')
await expectWithRetry(() => page.textContent('.cjs-clipboard')).toBe('ok')
})

test('dynamic imports from cjs dep (react)', async () => {
expect(await page.textContent('.cjs-dynamic button')).toBe('count is 0')
await expectWithRetry(() => page.textContent('.cjs-dynamic button')).toBe(
'count is 0',
)
await page.click('.cjs-dynamic button')
expect(await page.textContent('.cjs-dynamic button')).toBe('count is 1')
await expectWithRetry(() => page.textContent('.cjs-dynamic button')).toBe(
'count is 1',
)
})

test('dynamic named imports from webpacked cjs (phoenix)', async () => {
expect(await page.textContent('.cjs-dynamic-phoenix')).toBe('ok')
await expectWithRetry(() => page.textContent('.cjs-dynamic-phoenix')).toBe(
'ok',
)
})

test('dynamic default import from webpacked cjs (clipboard)', async () => {
expect(await page.textContent('.cjs-dynamic-clipboard')).toBe('ok')
await expectWithRetry(() => page.textContent('.cjs-dynamic-clipboard')).toBe(
'ok',
)
})

test('dynamic default import from cjs (cjs-dynamic-dep-cjs-compiled-from-esm)', async () => {
expect(await page.textContent('.cjs-dynamic-dep-cjs-compiled-from-esm')).toBe(
'ok',
)
await expectWithRetry(() =>
page.textContent('.cjs-dynamic-dep-cjs-compiled-from-esm'),
).toBe('ok')
})

test('dynamic default import from cjs (cjs-dynamic-dep-cjs-compiled-from-cjs)', async () => {
expect(await page.textContent('.cjs-dynamic-dep-cjs-compiled-from-cjs')).toBe(
'ok',
)
await expectWithRetry(() =>
page.textContent('.cjs-dynamic-dep-cjs-compiled-from-cjs'),
).toBe('ok')
})

test('dedupe', async () => {
expect(await page.textContent('.dedupe button')).toBe('count is 0')
await expectWithRetry(() => page.textContent('.dedupe button')).toBe(
'count is 0',
)
await page.click('.dedupe button')
expect(await page.textContent('.dedupe button')).toBe('count is 1')
await expectWithRetry(() => page.textContent('.dedupe button')).toBe(
'count is 1',
)
})

test('cjs browser field (axios)', async () => {
expect(await page.textContent('.cjs-browser-field')).toBe('pong')
await expectWithRetry(() => page.textContent('.cjs-browser-field')).toBe(
'pong',
)
})

test('cjs browser field bare', async () => {
expect(await page.textContent('.cjs-browser-field-bare')).toBe('pong')
await expectWithRetry(() => page.textContent('.cjs-browser-field-bare')).toBe(
'pong',
)
})

test('dep from linked dep (lodash-es)', async () => {
expect(await page.textContent('.deps-linked')).toBe('fooBarBaz')
await expectWithRetry(() => page.textContent('.deps-linked')).toBe(
'fooBarBaz',
)
})

test('forced include', async () => {
expect(await page.textContent('.force-include')).toMatch(`[success]`)
await expectWithRetry(() => page.textContent('.force-include')).toMatch(
`[success]`,
)
})

test('import * from optimized dep', async () => {
expect(await page.textContent('.import-star')).toMatch(`[success]`)
await expectWithRetry(() => page.textContent('.import-star')).toMatch(
`[success]`,
)
})

test('import from dep with process.env.NODE_ENV', async () => {
expect(await page.textContent('.node-env')).toMatch(isBuild ? 'prod' : 'dev')
await expectWithRetry(() => page.textContent('.node-env')).toMatch(
isBuild ? 'prod' : 'dev',
)
})

test('import from dep with .notjs files', async () => {
expect(await page.textContent('.not-js')).toMatch(`[success]`)
await expectWithRetry(() => page.textContent('.not-js')).toMatch(`[success]`)
})

test('Import from dependency which uses relative path which needs to be resolved by main field', async () => {
expect(await page.textContent('.relative-to-main')).toMatch(`[success]`)
await expectWithRetry(() => page.textContent('.relative-to-main')).toMatch(
`[success]`,
)
})

test('dep with dynamic import', async () => {
expect(await page.textContent('.dep-with-dynamic-import')).toMatch(
`[success]`,
)
await expectWithRetry(() =>
page.textContent('.dep-with-dynamic-import'),
).toMatch(`[success]`)
})

test('dep with optional peer dep', async () => {
expect(await page.textContent('.dep-with-optional-peer-dep')).toMatch(
`[success]`,
)
await expectWithRetry(() =>
page.textContent('.dep-with-optional-peer-dep'),
).toMatch(`[success]`)
if (isServe) {
expect(browserErrors.map((error) => error.message)).toEqual(
expect.arrayContaining([
Expand All @@ -109,8 +140,8 @@ test('dep with optional peer dep', async () => {
})

test('dep with optional peer dep submodule', async () => {
expect(
await page.textContent('.dep-with-optional-peer-dep-submodule'),
expectWithRetry(() =>
page.textContent('.dep-with-optional-peer-dep-submodule'),
).toMatch(`[success]`)
if (isServe) {
expect(browserErrors.map((error) => error.message)).toEqual(
Expand All @@ -122,61 +153,69 @@ test('dep with optional peer dep submodule', async () => {
})

test('dep with css import', async () => {
expect(await getColor('.dep-linked-include')).toBe('red')
await expectWithRetry(() => getColor('.dep-linked-include')).toBe('red')
})

test('CJS dep with css import', async () => {
expect(await getColor('.cjs-with-assets')).toBe('blue')
await expectWithRetry(() => getColor('.cjs-with-assets')).toBe('blue')
})

test('externalize known non-js files in optimize included dep', async () => {
expect(await page.textContent('.externalize-known-non-js')).toMatch(
`[success]`,
)
await expectWithRetry(() =>
page.textContent('.externalize-known-non-js'),
).toMatch(`[success]`)
})

test('vue + vuex', async () => {
expect(await page.textContent('.vue')).toMatch(`[success]`)
await expectWithRetry(() => page.textContent('.vue')).toMatch(`[success]`)
})

// When we use the Rollup CommonJS plugin instead of esbuild prebundling,
// the esbuild plugins won't apply to dependencies
test('esbuild-plugin', async () => {
expect(await page.textContent('.esbuild-plugin')).toMatch(
await expectWithRetry(() => page.textContent('.esbuild-plugin')).toMatch(
`Hello from an esbuild plugin`,
)
})

test('import from hidden dir', async () => {
expect(await page.textContent('.hidden-dir')).toBe('hello!')
await expectWithRetry(() => page.textContent('.hidden-dir')).toBe('hello!')
})

test('import optimize-excluded package that imports optimized-included package', async () => {
expect(await page.textContent('.nested-include')).toBe('nested-include')
await expectWithRetry(() => page.textContent('.nested-include')).toBe(
'nested-include',
)
})

test('import aliased package with colon', async () => {
expect(await page.textContent('.url')).toBe('vitejs.dev')
await expectWithRetry(() => page.textContent('.url')).toBe('vitejs.dev')
})

test('import aliased package using absolute path', async () => {
expect(await page.textContent('.alias-using-absolute-path')).toBe(
'From dep-alias-using-absolute-path',
)
await expectWithRetry(() =>
page.textContent('.alias-using-absolute-path'),
).toBe('From dep-alias-using-absolute-path')
})

test('variable names are reused in different scripts', async () => {
expect(await page.textContent('.reused-variable-names')).toBe('reused')
await expectWithRetry(() => page.textContent('.reused-variable-names')).toBe(
'reused',
)
})

test('flatten id should generate correctly', async () => {
expect(await page.textContent('.clonedeep-slash')).toBe('clonedeep-slash')
expect(await page.textContent('.clonedeep-dot')).toBe('clonedeep-dot')
await expectWithRetry(() => page.textContent('.clonedeep-slash')).toBe(
'clonedeep-slash',
)
await expectWithRetry(() => page.textContent('.clonedeep-dot')).toBe(
'clonedeep-dot',
)
})

test('non optimized module is not duplicated', async () => {
expect(
await page.textContent('.non-optimized-module-is-not-duplicated'),
await expectWithRetry(() =>
page.textContent('.non-optimized-module-is-not-duplicated'),
).toBe('from-absolute-path, from-relative-path')
})

Expand Down Expand Up @@ -227,8 +266,8 @@ test('pre bundle css require', async () => {
)
}

expect(await getColor('.css-require')).toBe('red')
expect(await getColor('.css-module-require')).toBe('red')
await expectWithRetry(() => getColor('.css-require')).toBe('red')
await expectWithRetry(() => getColor('.css-module-require')).toBe('red')
})

test.runIf(isBuild)('no missing deps during build', async () => {
Expand Down Expand Up @@ -276,5 +315,7 @@ describe.runIf(isServe)('optimizeDeps config', () => {
})

test('long file name should work', async () => {
expect(await page.textContent('.long-file-name')).toMatch(`hello world`)
await expectWithRetry(() => page.textContent('.long-file-name')).toMatch(
`hello world`,
)
})
20 changes: 20 additions & 0 deletions playground/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
import type { DepOptimizationMetadata, Manifest } from 'vite'
import { normalizePath } from 'vite'
import { fromComment } from 'convert-source-map'
import type { Assertion } from 'vitest'
import { expect } from 'vitest'
import type { ExecaChildProcess } from 'execa'
import { isBuild, isWindows, page, testDir } from './vitestSetup'
Expand Down Expand Up @@ -232,6 +233,25 @@ export async function withRetry(
await func()
}

export const expectWithRetry = <T>(getActual: () => Promise<T>) => {
type A = Assertion<T>
return new Proxy(
{},
{
get(_target, key) {
return async (...args) => {
await withRetry(
async () => expect(await getActual())[key](...args),
true,
)
}
},
},
) as {
[K in keyof A]: (...params: Parameters<A[K]>) => Promise<ReturnType<A[K]>>
}
}

type UntilBrowserLogAfterCallback = (logs: string[]) => PromiseLike<void> | void

export async function untilBrowserLogAfter(
Expand Down

0 comments on commit 4380b82

Please sign in to comment.