Skip to content
Draft
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
26 changes: 26 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,33 @@
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: ./.github/actions/setup
- uses: ./.github/actions/cypress-atomic-screenshots
storybook-atomic:
name: "Run Storybook tests"
needs: build
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright:v1.56.1-noble
options: --user 1001
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
shardTotal: [10]
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit

- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 0
filter: blob:none
- run: git branch main origin/main
- uses: ./.github/actions/setup
- run: npm run test:storybook -- --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
working-directory: packages/atomic
playwright-atomic-search-commerce-react-test:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
name: "Run e2e tests on Atomic Search Commerce React"
needs: affected
if: contains(needs.affected.outputs.projects, '@samples/atomic-search-commerce-react')
Expand Down
2 changes: 1 addition & 1 deletion packages/atomic/.storybook/Introduction.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ export const Default: StoryObj = {

export const Crawling: StoryObj = {
name: 'Crawling',
tags: ['!dev'],
tags: ['!dev', '!test'],
};
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ const config: StorybookConfig = {
{from: '../dist/atomic/lang', to: './lang'},
{from: './public', to: '/'},
],
addons: ['@storybook/addon-a11y', '@storybook/addon-docs'],
addons: [
'@storybook/addon-a11y',
'@storybook/addon-docs',
'@storybook/addon-vitest',
],
framework: {
name: '@storybook/web-components-vite',
options: {},
Expand Down
7 changes: 7 additions & 0 deletions packages/atomic/.storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ export const parameters: Parameters = {
controls: {
expanded: true,
},

a11y: {
// 'todo' - show a11y violations in the test UI only
// 'error' - fail CI on a11y violations
// 'off' - skip a11y checks entirely
test: 'todo',
},
};

export const decorators = [
Expand Down
14 changes: 14 additions & 0 deletions packages/atomic/.storybook/vitest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as a11yAddonAnnotations from '@storybook/addon-a11y/preview';
import {setProjectAnnotations} from '@storybook/web-components-vite';
import {beforeEach, vi} from 'vitest';
import * as projectAnnotations from './preview';

// Complement packages/atomic/vitest-utils/setup.ts by silencing console.warn and console.log as well (Storybook is a bit noisy atm).
beforeEach(async () => {
vi.spyOn(console, 'warn').mockImplementation(() => {});
vi.spyOn(console, 'log').mockImplementation(() => {});
});

// This is an important step to apply the right configuration when testing your stories.
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
setProjectAnnotations([a11yAddonAnnotations, projectAnnotations]);
7 changes: 5 additions & 2 deletions packages/atomic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@
"prod": "npx serve www -l 3333 --no-request-logging",
"test": "pnpm run test:stencil && pnpm run test:lit",
"test:stencil": "stencil test --spec -- src/utils/initialization-utils.spec.ts",
"test:lit": "vitest run",
"test:watch": "vitest",
"test:lit": "vitest run --project=atomic-default",
"test:watch": "vitest --project=atomic-default",
"test:storybook": "vitest run --project=storybook",
"e2e": "cypress run --browser chrome",
"e2e:firefox": "cypress run --browser firefox",
"e2e:watch": "cypress open --browser chrome --e2e",
Expand Down Expand Up @@ -113,6 +114,7 @@
"@stencil/react-output-target": "0.5.3",
"@storybook/addon-a11y": "9.1.2",
"@storybook/addon-docs": "9.1.2",
"@storybook/addon-vitest": "9.1.2",
"@storybook/icons": "1.4.0",
"@storybook/web-components-vite": "9.1.2",
"@tailwindcss/postcss": "4.1.13",
Expand All @@ -122,6 +124,7 @@
"@types/minimatch": "5.1.2",
"@types/node": "catalog:",
"@vitest/browser": "3.2.4",
"@vitest/coverage-v8": "^3.2.4",
"@wc-toolkit/storybook-helpers": "9.0.1",
"axe-core": "4.10.3",
"cypress": "catalog:",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,17 @@ const meta: Meta = {
},
args,
argTypes,

play: async (context) => {
await commerceInterfacePlay(context);
const canvas = within(context.canvasElement);
const searchBox = await canvas.findAllByShadowPlaceholderText('Search');
await userEvent.click(searchBox[0]);
//TODO KIT-5111: Remove beforeEach when refactored in preview.ts
beforeEach({canvasElement, canvas}) {
Object.assign(canvas, {...within(canvasElement)});
},
play: async ({mount, step, ...restOfContext}) => {
const canvas = (await mount()) as ReturnType<typeof within>;
await commerceInterfacePlay({mount, step, ...restOfContext});
await step('Click in the search box', async () => {
const searchBox = await canvas.findByShadowRole('textbox');
await userEvent.click(searchBox);
});
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const meta: Meta = {
argTypes,

play,
//TODO: Investigate https://coveord.atlassian.net/browse/KIT-5112
tags: ['!test'],
};

export default meta;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,19 @@ const meta: Meta = {

export default meta;

const {decorator: searchInterfaceDecorator, play: initializeSearchInterface} =
wrapInSearchInterface({
config: {
preprocessRequest: (request: any) => {
const parsed = JSON.parse(request.body as string);
parsed.numberOfResults = 4;
parsed.aq = '@source=iNaturalistTaxons';
request.body = JSON.stringify(parsed);
return request;
},
const {decorator, play} = wrapInSearchInterface({
config: {
preprocessRequest: (request: any) => {
const parsed = JSON.parse(request.body as string);
parsed.numberOfResults = 4;
parsed.aq = '@source=iNaturalistTaxons';
request.body = JSON.stringify(parsed);
return request;
},
skipFirstSearch: false,
includeCodeRoot: false,
});
},
skipFirstSearch: false,
includeCodeRoot: false,
});

export const Default: Story = {
name: 'In a folded result list',
Expand All @@ -165,9 +164,9 @@ export const Default: Story = {
</atomic-result-children>
</atomic-folded-result-list>
`,
searchInterfaceDecorator,
decorator,
],
afterEach: initializeSearchInterface,
play,
parameters: {
docs: {
source: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const meta: Meta = {
handles: events,
},
},
tags: ['!test'],
args,
argTypes,

Expand Down
4 changes: 4 additions & 0 deletions packages/atomic/turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
"dependsOn": ["^build", "build"],
"outputs": ["coverage/**"]
},
"test:storybook": {
"dependsOn": ["^build", "build"],
"outputs": []
},
"web:dev": {
"dependsOn": ["build"],
"cache": false,
Expand Down
41 changes: 39 additions & 2 deletions packages/atomic/vitest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {readFileSync} from 'node:fs';
import path, {dirname, resolve} from 'node:path';
import {storybookTest} from '@storybook/addon-vitest/vitest-plugin';
import tailwindcss from '@tailwindcss/vite';
import {configDefaults, defineConfig} from 'vitest/config';
import packageJsonHeadless from '../headless/package.json' with {type: 'json'};
Expand All @@ -23,7 +24,8 @@ function svgTransform(code, id) {
);
}

export default defineConfig({
const atomicDefault = defineConfig({
name: 'atomic-default',
define: {
'import.meta.env.RESOURCE_URL': `"${resourceUrl}"`,
__ATOMIC_VERSION__: `"${packageJson.version}"`,
Expand All @@ -35,7 +37,10 @@ export default defineConfig({
},
resolve: {
alias: [
{find: '@/', replacement: `${path.resolve(import.meta.dirname, './')}/`},
{
find: '@/',
replacement: `${path.resolve(import.meta.dirname, './')}/`,
},
{
find: /^@coveo\/headless\/(.*)$/,
replacement: path.resolve(
Expand Down Expand Up @@ -94,6 +99,7 @@ export default defineConfig({
},
],
test: {
name: 'atomic-default',
css: true,
include: ['src/**/*.spec.ts', 'scripts/stencil-proxy.spec.mjs'],
exclude: [
Expand All @@ -120,3 +126,34 @@ export default defineConfig({
},
},
});

// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon
const storybook = defineConfig({
name: 'storybook',
plugins: [
// The plugin will run tests for the stories defined in your Storybook config
// See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
storybookTest({
configDir: path.join(import.meta.dirname, '.storybook'),
storybookUrl: 'http://localhost:4400',
storybookScript: 'npx storybook dev -p 4400 --no-open',
}),
],
test: {
name: 'storybook',
fileParallelism: false,
browser: {
fileParallelism: false,
enabled: true,
headless: true,
provider: 'playwright',
instances: [{browser: 'chromium'}],
context: {
actionTimeout: 3000,
},
},
setupFiles: ['./vitest-utils/setup.ts', '.storybook/vitest.setup.ts'],
},
});

export default defineConfig({test: {projects: [atomicDefault, storybook]}});
9 changes: 6 additions & 3 deletions patches/@wc-toolkit+storybook-helpers+9.0.1.patch
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ index 1c0f4ce..1051420 100644
) : ""}
`;
}
@@ -705,18 +717,29 @@ function getSlotsTemplate(component, args, excludeCategories) {
@@ -705,18 +717,32 @@ function getSlotsTemplate(component, args, excludeCategories) {
${slotTemplates}
`) : "";
}
Expand All @@ -70,6 +70,9 @@ index 1c0f4ce..1051420 100644
+ containerElement = containerElement.shadowRoot;
+ }
+ const selectedComponent = containerElement.querySelector(component.tagName);
+ if(!selectedComponent) {
+ return;
+ }
argObserver?.observe(selectedComponent, {
- attributes: true
+ attributes: true,
Expand All @@ -84,7 +87,7 @@ index 1c0f4ce..1051420 100644
const { attrArgs: attributes } = getAttributesAndProperties(component);
if (argObserver) {
return;
@@ -726,13 +749,24 @@ function setArgObserver(component) {
@@ -726,13 +752,24 @@ function setArgObserver(component) {
if (mutation.attributeName === "class" && isUpdating) {
return;
}
Expand All @@ -110,7 +113,7 @@ index 1c0f4ce..1051420 100644
updateArgs({
[`${mutation.attributeName}`]: mutation.target.getAttribute(mutation.attributeName || "")
});
@@ -781,7 +815,8 @@ function getStorybookHelpers(tagName, options3) {
@@ -781,7 +818,8 @@ function getStorybookHelpers(tagName, options3) {
slot,
argTypes,
options3?.excludeCategories || [],
Expand Down
Loading
Loading