From 5e6de2742f329b7e65fe3dff4827b5134d777009 Mon Sep 17 00:00:00 2001 From: dsyddall Date: Sat, 12 Oct 2024 02:31:47 +0100 Subject: [PATCH] fix(runner): ensure sequential suite overrides sequence.concurrent (#6653) Co-authored-by: Hiroshi Ogawa --- packages/runner/src/suite.ts | 9 ++-- ...quence-concurrent-false-concurrent.test.ts | 31 ++++++++++++ ...quence-concurrent-false-sequential.test.ts | 31 ++++++++++++ ...equence-concurrent-true-concurrent.test.ts | 31 ++++++++++++ ...quence-concurrent-true-sequential.test.ts} | 18 +++---- test/config/test/sequence-concurrent.test.ts | 47 +++++++++++++++++++ 6 files changed, 152 insertions(+), 15 deletions(-) create mode 100644 test/config/fixtures/sequence-concurrent/sequence-concurrent-false-concurrent.test.ts create mode 100644 test/config/fixtures/sequence-concurrent/sequence-concurrent-false-sequential.test.ts create mode 100644 test/config/fixtures/sequence-concurrent/sequence-concurrent-true-concurrent.test.ts rename test/{core/test/sequential-sequence-concurrent.test.ts => config/fixtures/sequence-concurrent/sequence-concurrent-true-sequential.test.ts} (65%) create mode 100644 test/config/test/sequence-concurrent.test.ts diff --git a/packages/runner/src/suite.ts b/packages/runner/src/suite.ts index c935c3301341..3056bae4192a 100644 --- a/packages/runner/src/suite.ts +++ b/packages/runner/src/suite.ts @@ -520,16 +520,17 @@ function createSuite() { optionsOrFactory, ) + const isConcurrentSpecified = options.concurrent || this.concurrent || options.sequential === false + const isSequentialSpecified = options.sequential || this.sequential || options.concurrent === false + // inherit options from current suite if (currentSuite?.options) { options = { ...currentSuite.options, ...options } } // inherit concurrent / sequential from suite - const isConcurrent - = options.concurrent || (this.concurrent && !this.sequential) - const isSequential - = options.sequential || (this.sequential && !this.concurrent) + const isConcurrent = isConcurrentSpecified || (options.concurrent && !isSequentialSpecified) + const isSequential = isSequentialSpecified || (options.sequential && !isConcurrentSpecified) options.concurrent = isConcurrent && !isSequential options.sequential = isSequential && !isConcurrent diff --git a/test/config/fixtures/sequence-concurrent/sequence-concurrent-false-concurrent.test.ts b/test/config/fixtures/sequence-concurrent/sequence-concurrent-false-concurrent.test.ts new file mode 100644 index 000000000000..b9620007db9e --- /dev/null +++ b/test/config/fixtures/sequence-concurrent/sequence-concurrent-false-concurrent.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, test, vi } from 'vitest' + +const delay = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout)) + +let count = 0 + +describe.concurrent('concurrent suite', () => { + test('first test completes last', async ({ task }) => { + await delay(40) + expect(task.concurrent).toBeTruthy() + expect(++count).toBe(4) + }) + + test('second test completes third', async ({ task }) => { + await delay(30) + expect(task.concurrent).toBeTruthy() + expect(++count).toBe(3) + }) +}) + +test.concurrent('third test completes second', async ({ task }) => { + await delay(20) + expect(task.concurrent).toBeTruthy() + expect(++count).toBe(2) +}) + +test.concurrent('last test completes first', async ({ task }) => { + await delay(10) + expect(task.concurrent).toBeTruthy() + expect(++count).toBe(1) +}) diff --git a/test/config/fixtures/sequence-concurrent/sequence-concurrent-false-sequential.test.ts b/test/config/fixtures/sequence-concurrent/sequence-concurrent-false-sequential.test.ts new file mode 100644 index 000000000000..3dae2cf52e71 --- /dev/null +++ b/test/config/fixtures/sequence-concurrent/sequence-concurrent-false-sequential.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, test, vi } from 'vitest' + +const delay = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout)) + +let count = 0 + +describe('sequential suite', () => { + test('first test completes first', async ({ task }) => { + await delay(40) + expect(task.concurrent).toBeFalsy() + expect(++count).toBe(1) + }) + + test('second test completes second', async ({ task }) => { + await delay(30) + expect(task.concurrent).toBeFalsy() + expect(++count).toBe(2) + }) +}) + +test('third test completes third', async ({ task }) => { + await delay(20) + expect(task.concurrent).toBeFalsy() + expect(++count).toBe(3) +}) + +test('last test completes last', async ({ task }) => { + await delay(10) + expect(task.concurrent).toBeFalsy() + expect(++count).toBe(4) +}) diff --git a/test/config/fixtures/sequence-concurrent/sequence-concurrent-true-concurrent.test.ts b/test/config/fixtures/sequence-concurrent/sequence-concurrent-true-concurrent.test.ts new file mode 100644 index 000000000000..7f435a75b187 --- /dev/null +++ b/test/config/fixtures/sequence-concurrent/sequence-concurrent-true-concurrent.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, test, vi } from 'vitest' + +const delay = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout)) + +let count = 0 + +describe('concurrent suite', () => { + test('first test completes last', async ({ task }) => { + await delay(40) + expect(task.concurrent).toBeTruthy() + expect(++count).toBe(4) + }) + + test('second test completes third', async ({ task }) => { + await delay(30) + expect(task.concurrent).toBeTruthy() + expect(++count).toBe(3) + }) +}) + +test('third test completes second', async ({ task }) => { + await delay(20) + expect(task.concurrent).toBeTruthy() + expect(++count).toBe(2) +}) + +test('last test completes first', async ({ task }) => { + await delay(10) + expect(task.concurrent).toBeTruthy() + expect(++count).toBe(1) +}) diff --git a/test/core/test/sequential-sequence-concurrent.test.ts b/test/config/fixtures/sequence-concurrent/sequence-concurrent-true-sequential.test.ts similarity index 65% rename from test/core/test/sequential-sequence-concurrent.test.ts rename to test/config/fixtures/sequence-concurrent/sequence-concurrent-true-sequential.test.ts index d9304507761d..ed2772a7c939 100644 --- a/test/core/test/sequential-sequence-concurrent.test.ts +++ b/test/config/fixtures/sequence-concurrent/sequence-concurrent-true-sequential.test.ts @@ -1,35 +1,31 @@ import { describe, expect, test, vi } from 'vitest' -vi.setConfig({ - sequence: { - concurrent: true, - }, -}) - const delay = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout)) let count = 0 -describe.sequential('running sequential suite when sequence.concurrent is true', () => { +describe.sequential('sequential suite', () => { test('first test completes first', async ({ task }) => { - await delay(50) + await delay(40) expect(task.concurrent).toBeFalsy() expect(++count).toBe(1) }) - test('second test completes second', ({ task }) => { + test('second test completes second', async ({ task }) => { + await delay(30) expect(task.concurrent).toBeFalsy() expect(++count).toBe(2) }) }) test.sequential('third test completes third', async ({ task }) => { - await delay(50) + await delay(20) expect(task.concurrent).toBeFalsy() expect(++count).toBe(3) }) -test.sequential('fourth test completes fourth', ({ task }) => { +test.sequential('last test completes last', async ({ task }) => { + await delay(10) expect(task.concurrent).toBeFalsy() expect(++count).toBe(4) }) diff --git a/test/config/test/sequence-concurrent.test.ts b/test/config/test/sequence-concurrent.test.ts new file mode 100644 index 000000000000..a665e8f710a9 --- /dev/null +++ b/test/config/test/sequence-concurrent.test.ts @@ -0,0 +1,47 @@ +import { expect, test } from 'vitest' + +import { runVitest } from '../../test-utils' + +test('should run suites and tests concurrently unless sequential specified when sequence.concurrent is true', async () => { + const { stderr, stdout } = await runVitest({ + root: './fixtures/sequence-concurrent', + include: ['sequence-concurrent-true-*.test.ts'], + sequence: { + concurrent: true, + }, + }) + + expect(stderr).toBe('') + + expect(stdout).toContain('✓ sequence-concurrent-true-sequential.test.ts > sequential suite > first test completes first') + expect(stdout).toContain('✓ sequence-concurrent-true-sequential.test.ts > sequential suite > second test completes second') + expect(stdout).toContain('✓ sequence-concurrent-true-sequential.test.ts > third test completes third') + expect(stdout).toContain('✓ sequence-concurrent-true-sequential.test.ts > last test completes last') + expect(stdout).toContain('✓ sequence-concurrent-true-concurrent.test.ts > concurrent suite > first test completes last') + expect(stdout).toContain('✓ sequence-concurrent-true-concurrent.test.ts > concurrent suite > second test completes third') + expect(stdout).toContain('✓ sequence-concurrent-true-concurrent.test.ts > third test completes second') + expect(stdout).toContain('✓ sequence-concurrent-true-concurrent.test.ts > last test completes first') + expect(stdout).toContain('Test Files 2 passed (2)') +}) + +test('should run suites and tests sequentially unless concurrent specified when sequence.concurrent is false', async () => { + const { stderr, stdout } = await runVitest({ + root: './fixtures/sequence-concurrent', + include: ['sequence-concurrent-false-*.test.ts'], + sequence: { + concurrent: false, + }, + }) + + expect(stderr).toBe('') + + expect(stdout).toContain('✓ sequence-concurrent-false-sequential.test.ts > sequential suite > first test completes first') + expect(stdout).toContain('✓ sequence-concurrent-false-sequential.test.ts > sequential suite > second test completes second') + expect(stdout).toContain('✓ sequence-concurrent-false-sequential.test.ts > third test completes third') + expect(stdout).toContain('✓ sequence-concurrent-false-sequential.test.ts > last test completes last') + expect(stdout).toContain('✓ sequence-concurrent-false-concurrent.test.ts > concurrent suite > first test completes last') + expect(stdout).toContain('✓ sequence-concurrent-false-concurrent.test.ts > concurrent suite > second test completes third') + expect(stdout).toContain('✓ sequence-concurrent-false-concurrent.test.ts > third test completes second') + expect(stdout).toContain('✓ sequence-concurrent-false-concurrent.test.ts > last test completes first') + expect(stdout).toContain('Test Files 2 passed (2)') +})