Skip to content

Commit ae286b5

Browse files
committed
Add UI tests to stock level message on product page based
1 parent 0311fea commit ae286b5

File tree

6 files changed

+141
-0
lines changed

6 files changed

+141
-0
lines changed

core/tests/fixtures/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { CustomerFixture } from './customer';
1414
import { OrderFixture } from './order';
1515
import { extendedPage, toHaveURL } from './page';
1616
import { PromotionFixture } from './promotion';
17+
import { SettingsFixture } from './settings';
1718
import { WebPageFixture } from './webpage';
1819

1920
interface Fixtures {
@@ -23,6 +24,7 @@ interface Fixtures {
2324
customer: CustomerFixture;
2425
currency: CurrencyFixture;
2526
promotion: PromotionFixture;
27+
settings: SettingsFixture;
2628
webPage: WebPageFixture;
2729
/**
2830
* 'reuseCustomerSession' sets the the configuration for the customer fixture and determines whether to reuse the customer session.
@@ -107,6 +109,16 @@ export const test = baseTest.extend<Fixtures>({
107109
},
108110
{ scope: 'test' },
109111
],
112+
settings: [
113+
async ({ page }, use, currentTest) => {
114+
const settingsFixture = new SettingsFixture(page, currentTest);
115+
116+
await use(settingsFixture);
117+
118+
await settingsFixture.cleanup();
119+
},
120+
{ scope: 'test' },
121+
],
110122
webPage: [
111123
async ({ page }, use, currentTest) => {
112124
const webPageFixture = new WebPageFixture(page, currentTest);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Fixture } from '~/tests/fixtures/fixture';
2+
import { InventorySettings } from '~/tests/fixtures/utils/api/settings';
3+
4+
export class SettingsFixture extends Fixture {
5+
private initialInventorySettings: InventorySettings | null = null;
6+
7+
async getInventorySettings(): Promise<InventorySettings> {
8+
const settings = await this.api.settings.getInventorySettings();
9+
10+
return settings;
11+
}
12+
13+
async setInventorySettings(settings: InventorySettings): Promise<void> {
14+
if (!this.initialInventorySettings) {
15+
this.initialInventorySettings = await this.getInventorySettings();
16+
}
17+
18+
await this.api.settings.setInventorySettings(settings);
19+
}
20+
21+
async cleanup() {
22+
if (this.initialInventorySettings) {
23+
await this.api.settings.setInventorySettings(this.initialInventorySettings);
24+
}
25+
}
26+
}

core/tests/fixtures/utils/api/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { CurrenciesApi, currenciesHttpClient } from '~/tests/fixtures/utils/api/
44
import { CustomersApi, customersHttpClient } from '~/tests/fixtures/utils/api/customers';
55
import { OrdersApi, ordersHttpClient } from '~/tests/fixtures/utils/api/orders';
66
import { PromotionsApi, promotionsHttpClient } from '~/tests/fixtures/utils/api/promotions';
7+
import { SettingsApi, settingsHttpClient } from '~/tests/fixtures/utils/api/settings';
78
import { WebPagesApi, webPagesHttpClient } from '~/tests/fixtures/utils/api/webpages';
89

910
export interface ApiClient {
@@ -13,6 +14,7 @@ export interface ApiClient {
1314
currencies: CurrenciesApi;
1415
orders: OrdersApi;
1516
promotions: PromotionsApi;
17+
settings: SettingsApi;
1618
webPages: WebPagesApi;
1719
}
1820

@@ -23,5 +25,6 @@ export const httpApiClient: ApiClient = {
2325
currencies: currenciesHttpClient,
2426
orders: ordersHttpClient,
2527
promotions: promotionsHttpClient,
28+
settings: settingsHttpClient,
2629
webPages: webPagesHttpClient,
2730
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { z } from 'zod';
2+
3+
import { httpClient } from '../client';
4+
import { apiResponseSchema } from '../schema';
5+
6+
import { InventorySettings, SettingsApi } from '.';
7+
8+
const InventorySettingsSchema = z
9+
.object({
10+
default_out_of_stock_message: z.string(),
11+
show_out_of_stock_message: z.boolean(),
12+
stock_level_display: z.enum(['dont_show', 'show', 'show_when_low']).nullable(),
13+
})
14+
.transform(
15+
(data): InventorySettings => ({
16+
defaultOutOfStockMessage: data.default_out_of_stock_message,
17+
showOutOfStockMessage: data.show_out_of_stock_message,
18+
stockLevelDisplay: data.stock_level_display,
19+
}),
20+
);
21+
22+
const transformInventorySettingsData = (data: InventorySettings) => ({
23+
default_out_of_stock_message: data.defaultOutOfStockMessage,
24+
show_out_of_stock_message: data.showOutOfStockMessage,
25+
stock_level_display: data.stockLevelDisplay,
26+
});
27+
28+
export const settingsHttpClient: SettingsApi = {
29+
getInventorySettings: async (): Promise<InventorySettings> => {
30+
const resp = await httpClient
31+
.get(`/v3/settings/inventory`)
32+
.parse(apiResponseSchema(InventorySettingsSchema));
33+
34+
return resp.data;
35+
},
36+
setInventorySettings: async (settings: InventorySettings): Promise<void> => {
37+
await httpClient.put(`/v3/settings/inventory`, transformInventorySettingsData(settings));
38+
},
39+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export interface InventorySettings {
2+
readonly defaultOutOfStockMessage?: string;
3+
readonly showOutOfStockMessage?: boolean;
4+
readonly stockLevelDisplay?: 'dont_show' | 'show' | 'show_when_low' | null;
5+
}
6+
7+
export interface SettingsApi {
8+
getInventorySettings: () => Promise<InventorySettings>;
9+
setInventorySettings: (settings: InventorySettings) => Promise<void>;
10+
}
11+
12+
export { settingsHttpClient } from './http';

core/tests/ui/e2e/product.spec.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ test('Displays a simple product and can add it to the cart', async ({
3434

3535
test('Displays out of stock product correctly', async ({ page, catalog }) => {
3636
const t = await getTranslations('Product.ProductDetails');
37+
3738
const product = await catalog.createSimpleProduct({
3839
inventoryTracking: 'product',
3940
inventoryLevel: 0,
@@ -46,6 +47,54 @@ test('Displays out of stock product correctly', async ({ page, catalog }) => {
4647
await expect(page.getByRole('button', { name: t('Submit.outOfStock') })).toBeVisible();
4748
});
4849

50+
test('Displays out of stock product correctly when out of stock message is enabled', async ({
51+
page,
52+
catalog,
53+
settings,
54+
}) => {
55+
const t = await getTranslations('Product.ProductDetails');
56+
57+
await settings.setInventorySettings({
58+
showOutOfStockMessage: true,
59+
defaultOutOfStockMessage: 'Currently out of stock',
60+
});
61+
62+
const product = await catalog.createSimpleProduct({
63+
inventoryTracking: 'product',
64+
inventoryLevel: 0,
65+
});
66+
67+
await page.goto(product.path);
68+
await page.waitForLoadState('networkidle');
69+
70+
await expect(page.getByRole('heading', { name: product.name })).toBeVisible();
71+
await expect(page.getByRole('button', { name: t('Submit.outOfStock') })).toBeVisible();
72+
await expect(page.getByText('Currently out of stock')).toBeVisible();
73+
});
74+
75+
test('Displays current stock message when stock level message is enabled', async ({
76+
page,
77+
catalog,
78+
settings,
79+
}) => {
80+
const t = await getTranslations('Product.ProductDetails');
81+
82+
await settings.setInventorySettings({
83+
stockLevelDisplay: 'show',
84+
});
85+
86+
const product = await catalog.createSimpleProduct({
87+
inventoryTracking: 'product',
88+
inventoryLevel: 10,
89+
});
90+
91+
await page.goto(product.path);
92+
await page.waitForLoadState('networkidle');
93+
94+
await expect(page.getByRole('heading', { name: product.name })).toBeVisible();
95+
await expect(page.getByText(t('currentStock', { quantity: 10 }))).toBeVisible();
96+
});
97+
4998
test('Displays product price correctly for an alternate currency', async ({
5099
page,
51100
catalog,

0 commit comments

Comments
 (0)