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-product-price #4441

Merged
merged 9 commits into from
Oct 4, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {wrapInCommerceInterface} from '@coveo/atomic-storybook-utils/commerce/commerce-interface-wrapper';
import {wrapInCommerceProductList} from '@coveo/atomic-storybook-utils/commerce/commerce-product-list-wrapper';
import {wrapInProductTemplate} from '@coveo/atomic-storybook-utils/commerce/commerce-product-template-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: commerceInterfaceDecorator,
play: initializeCommerceInterface,
} = wrapInCommerceInterface({
skipFirstSearch: false,
type: 'product-listing',
engineConfig: {
context: {
view: {
url: 'https://sports.barca.group/browse/promotions/ui-kit-testing-product-price',
alexprudhomme marked this conversation as resolved.
Show resolved Hide resolved
},
language: 'en',
country: 'US',
currency: 'USD',
},
},
});

const {
decorator: commerceInterfaceDecoratorEUR,
play: initializeCommerceInterfaceEUR,
} = wrapInCommerceInterface({
skipFirstSearch: false,
type: 'product-listing',
engineConfig: {
context: {
view: {
url: 'https://sports.barca.group/browse/promotions/ui-kit-testing-product-price',
},
language: 'fr',
country: 'FR',
currency: 'EUR',
},
},
});

const {decorator: commerceProductListDecorator} = wrapInCommerceProductList();
const {decorator: productTemplateDecorator} = wrapInProductTemplate();

const meta: Meta = {
component: 'atomic-product-price',
title: 'Atomic-Commerce/Product Template Components/ProductPrice',
id: 'atomic-product-price',
render: renderComponent,
parameters,
};

export default meta;

export const Default: Story = {
name: 'atomic-product-price',
decorators: [
productTemplateDecorator,
commerceProductListDecorator,
commerceInterfaceDecorator,
],
play: initializeCommerceInterface,
};

export const WithEURCurrency: Story = {
decorators: [
productTemplateDecorator,
commerceProductListDecorator,
commerceInterfaceDecoratorEUR,
],
play: initializeCommerceInterfaceEUR,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {test, expect} from './fixture';

alexprudhomme marked this conversation as resolved.
Show resolved Hide resolved
test.describe('when there is no promotional price', async () => {
test.beforeEach(async ({productPrice}) => {
await productPrice.load();
await productPrice.hydrated.first().waitFor();
});

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

test('should render the price', async ({productPrice}) => {
expect(productPrice.blueLagoonPrice).toBeVisible();
});
});

test.describe('when there is a promotional price', async () => {
test.beforeEach(async ({productPrice}) => {
await productPrice.load();
await productPrice.hydrated.first().waitFor();
});

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

test('should render the original price with a line-through', async ({
productPrice,
}) => {
const promoPrice = productPrice.AquaMarinaPrice;
await expect(promoPrice).toBeVisible();
await expect(promoPrice).toHaveClass(/.*line-through.*/);
});

test('should render the promotional price with a text-error', async ({
productPrice,
}) => {
const promoPrice = productPrice.AquaMarinaPromoPrice;
await expect(promoPrice).toBeVisible();
await expect(promoPrice).toHaveClass(/.*text-error.*/);
});
});

test.describe('when the promotional price is higher than the original price', async () => {
test.beforeEach(async ({productPrice}) => {
await productPrice.withCustomPrices({price: 100, promoPrice: 200});
await productPrice.load();
});

test('should render the price', async ({page}) => {
const price = page.getByText('$100.00');
await expect(price).toBeVisible();
await expect(price).not.toHaveClass(/.*line-through.*/);
});

test('should not render the promotional price', async ({page}) => {
const promoPrice = page.getByText('$200.00');
await expect(promoPrice).not.toBeVisible();
});
});

test.describe('when the promotional price is the same as the original price', async () => {
test.beforeEach(async ({productPrice}) => {
await productPrice.withCustomPrices({price: 100, promoPrice: 100});
await productPrice.load();
});

test('should render the price', async ({page}) => {
const price = page.getByText('$100.00');
await expect(price).toBeVisible();
await expect(price).not.toHaveClass(/.*line-through.*/);
});

test('should not render the promotional price', async ({page}) => {
const promoPrice = page.getByText('$100.00');
await expect(promoPrice).not.toHaveClass(/.*text-error.*/);
});
});

test.describe('when given a invalid value', async () => {
test.beforeEach(async ({productPrice}) => {
await productPrice.withCustomPrices({price: NaN, promoPrice: NaN});
await productPrice.load();
});

test('should not render the price', async ({productPrice}) => {
await expect(productPrice.AquaMarinaPrice).not.toBeVisible();
await expect(productPrice.AquaMarinaPromoPrice).not.toBeVisible();
});
});

test('should render the price in the proper currency', async ({
productPrice,
page,
}) => {
await productPrice.load({story: 'with-eur-currency'});
await productPrice.hydrated.first().waitFor();

await expect(page.getByText('1 000,00 €')).toBeVisible();
await expect(page.getByText('39,00 €')).toBeVisible();
await expect(page.getByText('36,00 €')).toBeVisible();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {test as base} from '@playwright/test';
import {
makeAxeBuilder,
AxeFixture,
} from '../../../../../../playwright-utils/base-fixture';
import {ProductPricePageObject as ProductPrice} from './page-object';

type MyFixtures = {
productPrice: ProductPrice;
};

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

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

export class ProductPricePageObject extends BasePageObject<'atomic-product-price'> {
constructor(page: Page) {
super(page, 'atomic-product-price');
}

get blueLagoonPrice() {
return this.page.getByText('$1,000.00');
}

get AquaMarinaPrice() {
return this.page.getByText('$39.00');
}

get AquaMarinaPromoPrice() {
return this.page.getByText('$36.00');
}

async withCustomPrices({
price,
promoPrice,
}: {
price: number;
promoPrice: number;
}) {
await this.page.route('**/commerce/v2/listing', async (route) => {
const response = await route.fetch();
const body = await response.json();
body.products[0].ec_price = price;
body.products[0].ec_promo_price = promoPrice;
await route.fulfill({
response,
json: body,
});
});

return this;
}
}
1 change: 0 additions & 1 deletion packages/atomic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"extends": "./tsconfig.stencil.json",

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