Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Storybook] Rebase storybook onto Playwright integration #132

Merged
merged 11 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/js-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 18.x
- name: Build with lerna
- name: Build
run: |
corepack enable
yarn install
Expand Down
7 changes: 7 additions & 0 deletions visual-js/.changeset/early-jokes-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@saucelabs/visual-storybook": minor
"@saucelabs/visual-playwright": patch
"@saucelabs/visual": patch
---

Rebase Storybook integration onto Playwright
2 changes: 2 additions & 0 deletions visual-js/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
build
4 changes: 2 additions & 2 deletions visual-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"private": true,
"workspaces": [
"visual",
"visual-storybook",
"visual-wdio",
"visual-cypress",
"visual-nightwatch",
"visual-playwright"
"visual-playwright",
"visual-storybook"
],
"lint-staged": {
"**/*.{js,jsx,ts,tsx}": [
Expand Down
39 changes: 39 additions & 0 deletions visual-js/visual-playwright/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Sauce Labs Visual Playwright Integration

An extension for [Playwright](https://playwright.dev/) to integrate effortless visual testing with Sauce Labs Visual.

## Installation & Usage

View installation and usage instructions on the [Sauce Docs website](https://docs.saucelabs.com/visual-testing/integrations/playwright/).

## Building

Install the dependencies

```sh
npm install
```

Build [Sauce Labs Visual client library](../visual/) since Sauce Labs Visual Playwright Integration depends on it

```sh
npm --prefix ../visual run build
```

Finally build Sauce Labs Visual Playwright Integration

```sh
npm run build
```

## Linting

```sh
npm run lint
```

## Running the tests

```sh
npm run test
```
6 changes: 6 additions & 0 deletions visual-js/visual-playwright/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: ['/integration-tests'],
};
3 changes: 2 additions & 1 deletion visual-js/visual-playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"scripts": {
"build": "tsup-node",
"watch": "tsc-watch --declaration -p .",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\""
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
"test": "jest --collect-coverage"
},
"dependencies": {
"@playwright/test": "^1.42.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { beforeEach, describe, expect, it, jest } from '@jest/globals';

import { getApi as getVisualApi, waitForBuildResult } from './api';
import * as utils from './utils';
import type { MockInstance } from 'jest-mock';
import * as sauceVisual from '@saucelabs/visual';
import { BuildStatus, getApi } from '@saucelabs/visual';
import { MockInstance } from 'jest-mock';
import { BuildStatus, getEnvOpts, VisualApi } from '@saucelabs/visual';
import VisualPlaywright from './api';
import * as utils from './utils';

jest.mock('@saucelabs/visual', () => ({
...jest.requireActual<typeof sauceVisual>('@saucelabs/visual'),
getApi: () => ({
jest.mock('@saucelabs/visual', () => {
const apiResult = {
buildStatus: jest.fn(),
}),
}));
};
return {
...jest.requireActual<typeof sauceVisual>('@saucelabs/visual'),
getApi: () => apiResult,
};
});

describe('api', () => {
jest.spyOn(utils, 'getOpts').mockReturnValue(utils.getEnvOpts());
const consoleInfoSpy = jest
.spyOn(console, 'info')
// eslint-disable-next-line @typescript-eslint/no-empty-function
Expand All @@ -23,18 +24,18 @@ describe('api', () => {
.spyOn(console, 'error')
// eslint-disable-next-line @typescript-eslint/no-empty-function
.mockImplementation(() => {});
const apiMock = getVisualApi();
const buildStatusSpy = apiMock.buildStatus as unknown as MockInstance<
ReturnType<typeof getApi>['buildStatus']
>;
jest.spyOn(utils, 'getOpts').mockReturnValue({
...getEnvOpts(),
externalBuildId: true,
});
const buildStatusSpy = VisualPlaywright.api
.buildStatus as unknown as MockInstance<VisualApi['buildStatus']>;

beforeEach(() => {
jest.clearAllMocks();
});

const fakeBuild: Awaited<
ReturnType<ReturnType<typeof getApi>['buildStatus']>
> = {
const fakeBuild: Awaited<ReturnType<VisualApi['buildStatus']>> = {
__typename: 'Build',
status: BuildStatus.Running,
url: 'https://fake-url',
Expand All @@ -45,7 +46,7 @@ describe('api', () => {
describe('waitForBuildResult', () => {
it('should log a console error when a build is not found, and only query the API once', async () => {
buildStatusSpy.mockResolvedValue(null);
await waitForBuildResult('');
await VisualPlaywright.waitForBuildResult('');
expect(buildStatusSpy).toBeCalledTimes(1);
expect(consoleErrorSpy).toBeCalledTimes(1);
expect(consoleErrorSpy).toBeCalledWith(
Expand All @@ -64,7 +65,7 @@ describe('api', () => {
...fakeBuild,
status: BuildStatus.Equal,
});
await waitForBuildResult('');
await VisualPlaywright.waitForBuildResult('');
expect(buildStatusSpy).toBeCalledTimes(2);
expect(consoleInfoSpy).toBeCalledTimes(1);
expect(consoleInfoSpy).toBeCalledWith(
Expand All @@ -86,7 +87,7 @@ describe('api', () => {
...fakeBuild,
status: BuildStatus.Unapproved,
});
await waitForBuildResult('');
await VisualPlaywright.waitForBuildResult('');

// Should retry as many times as buildstatus === running
expect(buildStatusSpy).toBeCalledTimes(3);
Expand All @@ -97,7 +98,7 @@ describe('api', () => {
...fakeBuild,
status: BuildStatus.Equal,
});
await waitForBuildResult('');
await VisualPlaywright.waitForBuildResult('');

// Should retry as many times as buildstatus === running
expect(buildStatusSpy).toBeCalledTimes(1);
Expand Down
Loading