share step via globals.ts instead

This commit is contained in:
Simon Knott 2024-10-18 10:58:01 +02:00
parent d0dfbba7b6
commit 01c932f4bd
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
3 changed files with 32 additions and 14 deletions

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
import type { TestInfoImpl } from '../worker/testInfo';
import type { TestInfoImpl, TestStepInternal } from '../worker/testInfo';
import type { Suite } from './test';
let currentTestInfoValue: TestInfoImpl | null = null;
@ -42,3 +42,13 @@ export function setIsWorkerProcess() {
export function isWorkerProcess() {
return _isWorkerProcess;
}
let currentStepValue: TestStepInternal | undefined;
export function setCurrentStep(step: TestStepInternal | undefined) {
currentStepValue = step;
}
export function currentStep(): TestStepInternal | undefined {
return currentStepValue;
}

View file

@ -51,7 +51,7 @@ import {
} from './matchers';
import { toMatchSnapshot, toHaveScreenshot, toHaveScreenshotStepTitle } from './toMatchSnapshot';
import type { Expect, ExpectMatcherState } from '../../types/test';
import { currentTestInfo } from '../common/globals';
import { currentTestInfo, setCurrentStep } from '../common/globals';
import { filteredStackTrace, trimLongString } from '../util';
import {
expect as expectLibrary,
@ -322,8 +322,10 @@ class ExpectMetaInfoProxyHandler implements ProxyHandler<any> {
};
const step = testInfo._addStep(stepInfo);
setCurrentStep(step);
const reportStepError = (jestError: Error | unknown) => {
setCurrentStep(undefined);
const error = isExpectError(jestError) ? new ExpectError(jestError, customMessage, stackFrames) : jestError;
step.complete({ error });
if (this._info.isSoft)
@ -333,6 +335,7 @@ class ExpectMetaInfoProxyHandler implements ProxyHandler<any> {
};
const finalizer = () => {
setCurrentStep(undefined);
step.complete({});
};

View file

@ -16,7 +16,7 @@
import type { Locator, Page } from 'playwright-core';
import type { ExpectScreenshotOptions, Page as PageEx } from 'playwright-core/lib/client/page';
import { currentTestInfo } from '../common/globals';
import { currentStep, currentTestInfo } from '../common/globals';
import type { ImageComparatorOptions, Comparator } from 'playwright-core/lib/utils';
import { getComparator, sanitizeForFilePath } from 'playwright-core/lib/utils';
import {
@ -29,7 +29,7 @@ import { colors } from 'playwright-core/lib/utilsBundle';
import fs from 'fs';
import path from 'path';
import { mime } from 'playwright-core/lib/utilsBundle';
import type { TestInfoImpl } from '../worker/testInfo';
import type { TestInfoImpl, TestStepInternal } from '../worker/testInfo';
import type { ExpectMatcherState } from '../../types/test';
import type { MatcherResult } from './matcherHint';
import type { FullProjectInternal } from '../common/config';
@ -75,6 +75,7 @@ const NonConfigProperties: (keyof ToHaveScreenshotOptions)[] = [
class SnapshotHelper {
readonly testInfo: TestInfoImpl;
readonly step: TestStepInternal;
readonly attachmentBaseName: string;
readonly legacyExpectedPath: string;
readonly previousPath: string;
@ -91,6 +92,7 @@ class SnapshotHelper {
constructor(
testInfo: TestInfoImpl,
step: TestStepInternal,
matcherName: string,
locator: Locator | undefined,
anonymousSnapshotExtension: string,
@ -182,6 +184,7 @@ class SnapshotHelper {
this.comparator = getComparator(this.mimeType);
this.testInfo = testInfo;
this.step = step;
this.kind = this.mimeType.startsWith('image/') ? 'Screenshot' : 'Snapshot';
}
@ -224,9 +227,9 @@ class SnapshotHelper {
const isWriteMissingMode = this.updateSnapshots === 'all' || this.updateSnapshots === 'missing';
if (isWriteMissingMode)
writeFileSync(this.expectedPath, actual);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-expected'), contentType: this.mimeType, path: this.expectedPath });
this.step.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-expected'), contentType: this.mimeType, path: this.expectedPath });
writeFileSync(this.actualPath, actual);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-actual'), contentType: this.mimeType, path: this.actualPath });
this.step.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-actual'), contentType: this.mimeType, path: this.actualPath });
const message = `A snapshot doesn't exist at ${this.expectedPath}${isWriteMissingMode ? ', writing actual.' : '.'}`;
if (this.updateSnapshots === 'all') {
/* eslint-disable no-console */
@ -260,22 +263,22 @@ class SnapshotHelper {
// Copy the expectation inside the `test-results/` folder for backwards compatibility,
// so that one can upload `test-results/` directory and have all the data inside.
writeFileSync(this.legacyExpectedPath, expected);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-expected'), contentType: this.mimeType, path: this.expectedPath });
this.step.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-expected'), contentType: this.mimeType, path: this.expectedPath });
output.push(`\nExpected: ${colors.yellow(this.expectedPath)}`);
}
if (previous !== undefined) {
writeFileSync(this.previousPath, previous);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-previous'), contentType: this.mimeType, path: this.previousPath });
this.step.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-previous'), contentType: this.mimeType, path: this.previousPath });
output.push(`Previous: ${colors.yellow(this.previousPath)}`);
}
if (actual !== undefined) {
writeFileSync(this.actualPath, actual);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-actual'), contentType: this.mimeType, path: this.actualPath });
this.step.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-actual'), contentType: this.mimeType, path: this.actualPath });
output.push(`Received: ${colors.yellow(this.actualPath)}`);
}
if (diff !== undefined) {
writeFileSync(this.diffPath, diff);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-diff'), contentType: this.mimeType, path: this.diffPath });
this.step.attachments.push({ name: addSuffixToFilePath(this.attachmentBaseName, '-diff'), contentType: this.mimeType, path: this.diffPath });
output.push(` Diff: ${colors.yellow(this.diffPath)}`);
}
@ -299,7 +302,8 @@ export function toMatchSnapshot(
optOptions: ImageComparatorOptions = {}
): MatcherResult<NameOrSegments | { name?: NameOrSegments }, string> {
const testInfo = currentTestInfo();
if (!testInfo)
const step = currentStep();
if (!testInfo || !step)
throw new Error(`toMatchSnapshot() must be called during the test`);
if (received instanceof Promise)
throw new Error('An unresolved Promise was passed to toMatchSnapshot(), make sure to resolve it by adding await to it.');
@ -309,7 +313,7 @@ export function toMatchSnapshot(
const configOptions = testInfo._projectInternal.expect?.toMatchSnapshot || {};
const helper = new SnapshotHelper(
testInfo, 'toMatchSnapshot', undefined, determineFileExtension(received),
testInfo, step, 'toMatchSnapshot', undefined, determineFileExtension(received),
configOptions, nameOrOptions, optOptions);
if (this.isNot) {
@ -356,7 +360,8 @@ export async function toHaveScreenshot(
optOptions: ToHaveScreenshotOptions = {}
): Promise<MatcherResult<NameOrSegments | { name?: NameOrSegments }, string>> {
const testInfo = currentTestInfo();
if (!testInfo)
const step = currentStep();
if (!testInfo || !step)
throw new Error(`toHaveScreenshot() must be called during the test`);
if (testInfo._projectInternal.ignoreSnapshots)
@ -365,7 +370,7 @@ export async function toHaveScreenshot(
expectTypes(pageOrLocator, ['Page', 'Locator'], 'toHaveScreenshot');
const [page, locator] = pageOrLocator.constructor.name === 'Page' ? [(pageOrLocator as PageEx), undefined] : [(pageOrLocator as Locator).page() as PageEx, pageOrLocator as Locator];
const configOptions = testInfo._projectInternal.expect?.toHaveScreenshot || {};
const helper = new SnapshotHelper(testInfo, 'toHaveScreenshot', locator, 'png', configOptions, nameOrOptions, optOptions);
const helper = new SnapshotHelper(testInfo, step, 'toHaveScreenshot', locator, 'png', configOptions, nameOrOptions, optOptions);
if (!helper.expectedPath.toLowerCase().endsWith('.png'))
throw new Error(`Screenshot name "${path.basename(helper.expectedPath)}" must have '.png' extension`);
expectTypes(pageOrLocator, ['Page', 'Locator'], 'toHaveScreenshot');