Skip to content

Commit

Permalink
test(atomic): add tests for atomic-product-price (#4441)
Browse files Browse the repository at this point in the history
https://coveord.atlassian.net/browse/KIT-3271

wait for #4408 to merge before
continuing
  • Loading branch information
alexprudhomme authored Oct 4, 2024
1 parent 80e6ba1 commit 09c56b4
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 1 deletion.
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',
},
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';

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"]
}

0 comments on commit 09c56b4

Please sign in to comment.