diff --git a/src/matchers.test.ts b/src/matchers.test.ts index cec929b4..ce53b278 100644 --- a/src/matchers.test.ts +++ b/src/matchers.test.ts @@ -73,5 +73,17 @@ describe('matchers.ts', () => { expect(result.pass).toBe(false); expect(writeFileMock).toHaveBeenCalledTimes(1); }); + + it('should return early, skipping the comparison if the latestPath is the baseline path (fresh screenshot)', () => { + const latestPath = 'baseline/ios/screen.png'; + + const result = toMatchBaseline(latestPath); + + expect(result.message()).toBe( + 'Generated a fresh baseline, skipping comparison.' + ); + expect(result.pass).toBe(true); + expect(writeFileMock).toHaveBeenCalledTimes(0); + }); }); }); diff --git a/src/matchers.ts b/src/matchers.ts index d24e48c1..30e44a59 100644 --- a/src/matchers.ts +++ b/src/matchers.ts @@ -24,6 +24,13 @@ export const toMatchBaseline = (latestPath: string) => { path.basename(latestPath) ); + if (latestPath === baselinePath) { + return { + message: () => 'Generated a fresh baseline, skipping comparison.', + pass: true, + }; + } + const diffPath = path.join( screenshotsDir, 'diff', diff --git a/src/take-screenshot.test.ts b/src/take-screenshot.test.ts index 06614d0a..b4cac886 100644 --- a/src/take-screenshot.test.ts +++ b/src/take-screenshot.test.ts @@ -2,6 +2,7 @@ import execa from 'execa'; import path from 'path'; import { takeScreenshot } from './take-screenshot'; +import * as fileExistsHelpers from './utils/file-exists'; const SCREENSHOT_FILENAME = 'screen'; @@ -75,6 +76,8 @@ describe('take-screenshot.ts', () => { }); it('should take a screenshot', async () => { + jest.spyOn(fileExistsHelpers, 'fileExists').mockResolvedValueOnce(true); + await takeScreenshot(SCREENSHOT_FILENAME); expect(commandMock).toHaveBeenCalledWith( @@ -86,6 +89,19 @@ describe('take-screenshot.ts', () => { } ); }); + + it('should take a screenshot - baseline does not exist', async () => { + await takeScreenshot(SCREENSHOT_FILENAME); + + expect(commandMock).toHaveBeenCalledWith( + 'xcrun simctl io booted screenshot screen.png', + { + cwd: path.join(process.cwd(), '.owl', 'baseline', 'ios'), + shell: false, + stdio: 'ignore', + } + ); + }); }); describe('Android', () => { @@ -95,6 +111,8 @@ describe('take-screenshot.ts', () => { }); it('should take a screenshot', async () => { + jest.spyOn(fileExistsHelpers, 'fileExists').mockResolvedValueOnce(true); + await takeScreenshot(SCREENSHOT_FILENAME); expect(commandMock).toHaveBeenCalledWith( @@ -106,6 +124,19 @@ describe('take-screenshot.ts', () => { } ); }); + + it('should take a screenshot - baseline does not exist', async () => { + await takeScreenshot(SCREENSHOT_FILENAME); + + expect(commandMock).toHaveBeenCalledWith( + 'adb exec-out screencap -p > screen.png', + { + cwd: path.join(process.cwd(), '.owl', 'baseline', 'android'), + shell: true, + stdio: 'ignore', + } + ); + }); }); }); }); diff --git a/src/take-screenshot.ts b/src/take-screenshot.ts index d13bf07f..7a39f10f 100644 --- a/src/take-screenshot.ts +++ b/src/take-screenshot.ts @@ -2,8 +2,9 @@ import execa from 'execa'; import { promises as fs } from 'fs'; import path from 'path'; -import { Platform } from './cli/types'; +import { fileExists } from './utils/file-exists'; import { Logger } from './logger'; +import { Platform } from './cli/types'; /** * Takes a screenshot from the simulator. @@ -22,7 +23,10 @@ export const takeScreenshot = async (filename: string): Promise => { const screenshotsDirPath = path.join(process.cwd(), '.owl'); await fs.mkdir(screenshotsDirPath, { recursive: true }); - const DIR_NAME = updateBaseline ? 'baseline' : 'latest'; + const baselineExist = await fileExists( + path.join(screenshotsDirPath, 'baseline', platform, screenshotFilename) + ); + const DIR_NAME = updateBaseline || !baselineExist ? 'baseline' : 'latest'; const cwd = path.join(screenshotsDirPath, DIR_NAME, platform); await fs.mkdir(cwd, { recursive: true }); diff --git a/src/utils/file-exists.ts b/src/utils/file-exists.ts new file mode 100644 index 00000000..208d5eff --- /dev/null +++ b/src/utils/file-exists.ts @@ -0,0 +1,10 @@ +import { promises as fs } from 'fs'; + +export const fileExists = async (filePath: string): Promise => { + try { + await fs.access(filePath); + return true; + } catch { + return false; + } +};