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

test(atomic): add tests for atomic-commerce-recommendation-list #4437

Merged
merged 49 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
bb2d2e7
create files
alexprudhomme Jul 26, 2024
38a4922
export field in headless
alexprudhomme Sep 10, 2024
8e0e80a
no hashing file storybook + vite
alexprudhomme Sep 10, 2024
6627810
new bundle for atomic-react
alexprudhomme Sep 10, 2024
60684c4
Revert "new bundle for atomic-react"
alexprudhomme Sep 10, 2024
af5cd1e
simply not supporting CJS
alexprudhomme Sep 10, 2024
041d56d
main import is ESM
alexprudhomme Sep 10, 2024
c1ba10a
run storybook tests on local build, skip iife sample test for now
alexprudhomme Sep 10, 2024
39c6d4b
atomic insgith pane et screenshot
alexprudhomme Sep 10, 2024
960814e
Merge branch 'master' into KIT-2541-1
alexprudhomme Sep 10, 2024
301b09f
skip failing tests
alexprudhomme Sep 11, 2024
2b05660
re add CJS output of atomic-react
alexprudhomme Sep 11, 2024
fed87f8
Update main.mts
alexprudhomme Sep 11, 2024
31a03a7
start writing tests for recs-interface
alexprudhomme Sep 16, 2024
1d85424
test for recs-interface
alexprudhomme Sep 17, 2024
9041800
Merge branch 'master' into KIT-3540
alexprudhomme Sep 17, 2024
3fe95e9
recs list tests
alexprudhomme Sep 18, 2024
55cb1d7
tests for atomic-external
alexprudhomme Sep 18, 2024
e84af49
remove all cypress tests
alexprudhomme Sep 18, 2024
f68955a
Merge branch 'master' into KIT-3540
alexprudhomme Sep 18, 2024
ac59594
Merge branch 'master' into KIT-3540
alexprudhomme Sep 18, 2024
1a94cf7
working external story
alexprudhomme Sep 18, 2024
bcfc8ea
fix external atomic test
alexprudhomme Sep 18, 2024
6da86c2
Merge branch 'master' into KIT-3540
alexprudhomme Sep 18, 2024
f36a773
Update packages/atomic/src/components/recommendations/atomic-recs-int…
alexprudhomme Sep 18, 2024
44e213e
some comments
alexprudhomme Sep 18, 2024
0932ef8
Merge branch 'KIT-3540' of https://github.com/coveo/ui-kit into KIT-3540
alexprudhomme Sep 18, 2024
5d7c035
test with no recommendations
alexprudhomme Sep 18, 2024
fa680c9
no textarea
alexprudhomme Sep 18, 2024
90ea663
add waitfornetworkidle
alexprudhomme Sep 18, 2024
a1bbdaa
Merge branch 'master' into KIT-3248
alexprudhomme Sep 18, 2024
f03a987
Merge branch 'KIT-3540' into KIT-3248
alexprudhomme Sep 19, 2024
f9fb15b
Merge branch 'master' into KIT-3540
alexprudhomme Sep 24, 2024
2b95754
Merge branch 'KIT-3540' into KIT-3248
alexprudhomme Sep 24, 2024
fa5bc55
Merge branch 'master' into KIT-3540
alexprudhomme Sep 24, 2024
59cbad8
fix build
alexprudhomme Sep 24, 2024
2adab33
Merge branch 'KIT-3540' of https://github.com/coveo/ui-kit into KIT-3540
alexprudhomme Sep 24, 2024
16987f2
Merge branch 'KIT-3540' into KIT-3248
alexprudhomme Sep 24, 2024
a5ee456
fix build
alexprudhomme Sep 24, 2024
2f636b3
Update atomic-commerce-recommendation-list.new.stories.tsx
alexprudhomme Sep 24, 2024
a67f88b
add all stories
alexprudhomme Sep 24, 2024
9d698de
Merge branch 'master' into KIT-3540
alexprudhomme Sep 25, 2024
e25da21
Merge branch 'master' into KIT-3540
alexprudhomme Sep 26, 2024
89544fd
Merge branch 'KIT-3540' into KIT-3248
alexprudhomme Sep 26, 2024
f613f2f
add tests
alexprudhomme Sep 26, 2024
2b5e371
Update atomic-recs-list.e2e.ts
alexprudhomme Sep 26, 2024
cb8e04d
Merge branch 'master' into KIT-3248
alexprudhomme Sep 27, 2024
6d81d35
rec list is hidden instead of not rendered
alexprudhomme Sep 27, 2024
0697d0d
Merge branch 'master' into KIT-3248
alexprudhomme Sep 27, 2024
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
14 changes: 14 additions & 0 deletions packages/atomic/playwright-utils/base-page-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ export class BasePageObject<
return this;
}

async noRecommendations() {
await this.page.route('**/commerce/v2/recommendations', async (route) => {
const response = await route.fetch();
const body = await response.json();
body.products = [];
await route.fulfill({
response,
json: body,
});
});

return this;
}

private camelToKebab(args: Component) {
const toKebab: Record<string, unknown> = {};
Object.entries(args as Record<string, unknown>).forEach(([key, value]) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import {wrapInCommerceInterface} from '@coveo/atomic-storybook-utils/commerce/commerce-interface-wrapper';
import {parameters} from '@coveo/atomic-storybook-utils/common/common-meta-parameters';
import {renderComponent} from '@coveo/atomic-storybook-utils/common/render-component';
import type {Meta, StoryObj as Story} from '@storybook/web-components';

const {decorator, play} = wrapInCommerceInterface({skipFirstSearch: false});

const meta: Meta = {
component: 'atomic-commerce-recommendation-list',
title: 'Atomic-Commerce/Atomic Recommendation List',
id: 'atomic-commerce-recommendation-list',
render: renderComponent,
decorators: [decorator],
parameters,
play,
args: {
'attributes-slot-id': 'd8118c04-ff59-4f03-baca-2fc5f3b81221',
'slots-default': `<atomic-product-template>
<template>
<atomic-product-section-name>
<atomic-product-link class="font-bold"></atomic-product-link>
</atomic-product-section-name>
<atomic-product-section-visual>
<atomic-product-image field="ec_thumbnails"></atomic-product-image>
</atomic-product-section-visual>
<atomic-product-section-metadata>
<atomic-product-text field="ec_brand" class="text-neutral-dark block"></atomic-product-text>
<atomic-product-rating field="ec_rating"></atomic-product-rating>
</atomic-product-section-metadata>
<atomic-product-section-emphasized>
<atomic-product-price currency="USD"></atomic-product-price>
</atomic-product-section-emphasized>
<atomic-product-section-children>
<atomic-product-children></atomic-product-children>
</atomic-product-section-children>
</template>
</atomic-product-template>`,
},
};
export default meta;

export const Default: Story = {
name: 'atomic-commerce-recommendation-list',
};

const {play: playNoFirstQuery} = wrapInCommerceInterface({
skipFirstSearch: true,
});
export const BeforeQuery: Story = {
tags: ['test'],
play: playNoFirstQuery,
};

export const WithFullTemplate: Story = {
tags: ['test'],
args: {
'slots-default': ` <atomic-product-template>
<template>
<atomic-product-section-visual>
<span>Visual Section</span>
</atomic-product-section-visual>
<atomic-product-section-badge>
<span>Badge Section</span>
</atomic-product-section-badge>
<atomic-product-section-actions>
<span>Actions Section</span>
</atomic-product-section-actions>
<atomic-product-section-title>
<span>Title Section</span>
</atomic-product-section-title>
<atomic-product-section-title-metadata>
<span>Title Metadata Section</span>
</atomic-product-section-title-metadata>
<atomic-product-section-emphasized>
<span>Emphasized Section</span>
</atomic-product-section-emphasized>
<atomic-product-section-excerpt>
<span>Excerpt Section</span>
</atomic-product-section-excerpt>
<atomic-product-section-bottom-metadata>
<span>Bottom Metadata Section</span>
</atomic-product-section-bottom-metadata>
</template>
</atomic-product-template>`,
},
};

export const AsCarousel: Story = {
args: {
'attributes-products-per-page': 3,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {randomID} from '../../../utils/utils';
import {ResultsPlaceholdersGuard} from '../../common/atomic-result-placeholder/placeholders';
import {Carousel} from '../../common/carousel';
import {Heading} from '../../common/heading';
import {Hidden} from '../../common/hidden';
import {DisplayGrid} from '../../common/item-list/display-grid';
import {DisplayWrapper} from '../../common/item-list/display-wrapper';
import {ItemDisplayGuard} from '../../common/item-list/item-display-guard';
Expand Down Expand Up @@ -56,6 +57,8 @@ import {SelectChildProductEventArgs} from '../product-template-components/atomic
* @part indicators - The list of indicators.
* @part indicator - A single indicator.
* @part active-indicator - The active indicator.
*
* @slot default - The default slot where the product templates are defined.
*/
@Component({
tag: 'atomic-commerce-recommendation-list',
Expand Down Expand Up @@ -409,7 +412,7 @@ export class AtomicCommerceRecommendationList
public render() {
if (this.hasNoProducts) {
this.bindings.store.unsetLoadingFlag(this.loadingFlag);
return;
return <Hidden></Hidden>;
}
return (
<Fragment>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import {test, expect} from './fixture';

test.describe('before query is loaded', () => {
test.beforeEach(async ({recommendationList}) => {
await recommendationList.load({story: 'before-query'});
await recommendationList.hydrated.waitFor();
});

test('should be a11y compliant', async ({makeAxeBuilder}) => {
const accessibilityResults = await makeAxeBuilder().analyze();
expect(accessibilityResults.violations.length).toEqual(0);
});

test('should have placeholders', async ({recommendationList}) => {
await expect(recommendationList.placeholder.first()).toBeVisible();
});
});

test.describe('after query is loaded', () => {
test.beforeEach(async ({recommendationList}) => {
await recommendationList.load({story: 'default'});
await recommendationList.hydrated.waitFor();
});

test('should be a11y compliant', async ({makeAxeBuilder}) => {
const accessibilityResults = await makeAxeBuilder().analyze();
expect(accessibilityResults.violations.length).toEqual(0);
});

test('should have recommendations', async ({recommendationList}) => {
await expect(recommendationList.recommendation.first()).toBeVisible();
});
});

test.describe('with a full result template', () => {
test.beforeEach(async ({recommendationList}) => {
await recommendationList.load({story: 'with-full-template'});
await recommendationList.hydrated.waitFor();
});

test('should be a11y compliant', async ({makeAxeBuilder}) => {
const accessibilityResults = await makeAxeBuilder().analyze();
expect(accessibilityResults.violations.length).toEqual(0);
});

test('should have recommendations', async ({recommendationList}) => {
await expect(recommendationList.recommendation.first()).toBeVisible();
});
});

test.describe('with a carousel', () => {
test.beforeEach(async ({recommendationList}) => {
await recommendationList.load({story: 'as-carousel'});
await recommendationList.hydrated.waitFor();
});

test('should be a11y compliant', async ({makeAxeBuilder}) => {
const accessibilityResults = await makeAxeBuilder().analyze();
expect(accessibilityResults.violations.length).toEqual(0);
});

test('should have recommendations', async ({recommendationList}) => {
await expect(recommendationList.recommendation.first()).toBeVisible();
});

test('should support going forward and backward', async ({
recommendationList,
}) => {
await recommendationList.nextButton.click();
await expect(recommendationList.indicators.nth(1)).toHaveAttribute(
'part',
'indicator active-indicator'
);

await recommendationList.prevButton.click();
await recommendationList.prevButton.click();
await expect(recommendationList.indicators.nth(3)).toHaveAttribute(
'part',
'indicator active-indicator'
);

await recommendationList.nextButton.click();
await expect(recommendationList.indicators.nth(0)).toHaveAttribute(
'part',
'indicator active-indicator'
);
});
});

test('with no recommendations returned by the API, should render placeholders', async ({
recommendationList,
}) => {
await recommendationList.noRecommendations();
await recommendationList.load({story: 'default'});
await recommendationList.hydrated.waitFor({state: 'hidden'});
await expect
.poll(async () => await recommendationList.recommendation.count())
.toBe(0);
await expect
.poll(async () => await recommendationList.placeholder.count())
.toBe(0);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {test as base} from '@playwright/test';
import {
AxeFixture,
makeAxeBuilder,
} from '../../../../../playwright-utils/base-fixture';
import {AtomicCommerceRecommendationList as RecommendationList} from './page-object';

type MyFixtures = {
recommendationList: RecommendationList;
};

export const test = base.extend<MyFixtures & AxeFixture>({
makeAxeBuilder,
recommendationList: async ({page}, use) => {
await use(new RecommendationList(page));
},
});

export {expect} from '@playwright/test';
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type {Page} from '@playwright/test';
import {BasePageObject} from '../../../../../playwright-utils/base-page-object';

export class AtomicCommerceRecommendationList extends BasePageObject<'atomic-commerce-recommendation-list'> {
constructor(page: Page) {
super(page, 'atomic-commerce-recommendation-list');
}

get placeholder() {
return this.page.locator('.placeholder');
}

get recommendation() {
return this.page.locator(
'[part="result-list-grid-clickable-container outline"]'
);
}

get indicators() {
return this.page.getByRole('listitem');
}

get nextButton() {
return this.page.getByLabel('Next');
}

get prevButton() {
return this.page.getByLabel('Previous');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ test.describe('before query is loaded', () => {
await recsList.hydrated.waitFor();
});

test('should be ally compliant', async ({makeAxeBuilder}) => {
test('should be a11y compliant', async ({makeAxeBuilder}) => {
const accessibilityResults = await makeAxeBuilder().analyze();
expect(accessibilityResults.violations.length).toEqual(0);
});
Expand All @@ -22,7 +22,7 @@ test.describe('after query is loaded', () => {
await recsList.hydrated.waitFor();
});

test('should be ally compliant', async ({makeAxeBuilder}) => {
test('should be a11y compliant', async ({makeAxeBuilder}) => {
const accessibilityResults = await makeAxeBuilder().analyze();
expect(accessibilityResults.violations.length).toEqual(0);
});
Expand All @@ -38,7 +38,7 @@ test.describe('with a full result template', () => {
await recsList.hydrated.waitFor();
});

test('should be ally compliant', async ({makeAxeBuilder}) => {
test('should be a11y compliant', async ({makeAxeBuilder}) => {
const accessibilityResults = await makeAxeBuilder().analyze();
expect(accessibilityResults.violations.length).toEqual(0);
});
Expand All @@ -54,7 +54,7 @@ test.describe('with a carousel', () => {
await recsList.hydrated.waitFor();
});

test('should be ally compliant', async ({makeAxeBuilder}) => {
test('should be a11y compliant', async ({makeAxeBuilder}) => {
const accessibilityResults = await makeAxeBuilder().analyze();
expect(accessibilityResults.violations.length).toEqual(0);
});
Expand Down
9 changes: 2 additions & 7 deletions packages/atomic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
{
"extends": "./tsconfig.stencil.json",
"exclude": [
"node_modules",
"src/external-builds",
"**/*.stories.tsx",
"**/*.stories.ts",
"**/*.stories.js"
]

"exclude": ["node_modules", "src/external-builds"]
}
Loading