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

Refactor page object usage #32

Merged
merged 6 commits into from
Jun 11, 2024
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
with: # do not change the order of params
target-branch: ${{ github.event.pull_request.base.ref }} #required
current-branch: ${{ github.event.pull_request.head.ref }} #required
pattern: '^\s*(feat|fix|ci|chore|docs|test|style|refactor)(\(.{1,}\))?: .{1,}$' #optional custom validation commit
pattern: '^\s*(feat|fix|ci|chore|docs|test|style|refactor|BREAKING CHANGE)(\(.{1,}\))?: .{1,}$' #optional custom validation commit
test:
timeout-minutes: 15
runs-on: ubuntu-latest
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ There are several page objects to navigate the different pages of the Administra
```TypeScript
import { test, expect } from './../BaseTestFile';

test('Storefront cart test scenario', async ({ StorefrontCheckoutCart }) => {
test('Storefront cart test scenario', async ({ StorefrontPage, StorefrontCheckoutCart }) => {

await StorefrontCheckoutCart.goTo();
await StorefrontPage.goto(StorefrontCheckoutCart.url());
await expect(StorefrontCheckoutCart.grandTotalPrice).toHaveText('€100.00*');
});
```
Expand All @@ -236,7 +236,7 @@ The actor class is just a lightweight solution to simplify the execution of reus
* `page`: A Playwright page context the actor is navigating.

**Methods**
* `goesTo`: Accepts a page object the actor should be navigating to.
* `goesTo`: Accepts an url of a page the actor should navigate to.
* `attemptsTo`: Accepts a "task" function with reusable test logic the actor should perform.
* `expects`: A one-to-one export of the Playwright `expect` method to use it in the actor pattern.

Expand All @@ -257,7 +257,7 @@ test('Product detail test scenario', async ({
ProductData
}) => {

await ShopCustomer.goesTo(StorefrontProductDetail);
await ShopCustomer.goesTo(StorefrontProductDetail.url(ProductData));
await ShopCustomer.attemptsTo(AddProductToCart(ProductData));
await ShopCustomer.expects(StorefrontProductDetail.offCanvasSummaryTotalPrice).toHaveText('€99.99*');
});
Expand Down Expand Up @@ -289,7 +289,7 @@ export const Login = base.extend<{ Login: Task }, FixtureTypes>({
return async function Login() {
const { customer } = DefaultSalesChannel;

await ShopCustomer.goesTo(StorefrontAccountLogin);
await ShopCustomer.goesTo(StorefrontAccountLogin.url());

await StorefrontAccountLogin.emailInput.fill(customer.email);
await StorefrontAccountLogin.passwordInput.fill(customer.password);
Expand Down
46 changes: 27 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"prepublishOnly": "npm run build"
},
"dependencies": {
"@playwright/test": "1.44.0",
"@playwright/test": "^1.44.1",
"@shopware/api-client": "0.5.0",
"@axe-core/playwright": "4.9.1",
"axe-html-reporter": "2.2.3",
Expand Down
4 changes: 2 additions & 2 deletions src/data-fixtures/Category/Category.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { test as base, expect } from '@playwright/test';
import type { FixtureTypes } from '../../types/FixtureTypes';
import type { components } from '@shopware/api-client/admin-api-types';
import type { Category } from '../../types/ShopwareTypes';

export const CategoryData = base.extend<FixtureTypes>({
CategoryData: async ({ IdProvider, AdminApiContext, DefaultSalesChannel, ProductData }, use) => {
Expand All @@ -26,7 +26,7 @@ export const CategoryData = base.extend<FixtureTypes>({

expect(categoryResponse.ok()).toBeTruthy();

const { data: category } = (await categoryResponse.json()) as { data: components['schemas']['Category'] };
const { data: category } = (await categoryResponse.json()) as { data: Category };

await use(category);

Expand Down
9 changes: 5 additions & 4 deletions src/data-fixtures/DataFixtures.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { mergeTests } from '@playwright/test';
import type { components } from '@shopware/api-client/admin-api-types';
import type { Product, Category, Order } from '../types/ShopwareTypes';
import { ProductData } from './Product/Product';
import { CategoryData } from './Category/Category';
import { DigitalProductData } from './Product/DigitalProduct';
Expand All @@ -11,10 +12,10 @@ import { OrderData } from './Order/Order';
import { TagData } from './Tag/Tag';

export interface DataFixtureTypes {
ProductData: components['schemas']['Product'],
CategoryData: components['schemas']['Category'],
ProductData: Product,
CategoryData: Category,
DigitalProductData: {
product: components['schemas']['Product'],
product: Product,
fileContent: string
},
PromotionWithCodeData: components['schemas']['Promotion'],
Expand All @@ -24,7 +25,7 @@ export interface DataFixtureTypes {
propertyGroupSize: components['schemas']['PropertyGroup']
},
MediaData: components['schemas']['Media'],
OrderData: components['schemas']['Order'],
OrderData: Order,
TagData: components['schemas']['Tag'],
}

Expand Down
4 changes: 2 additions & 2 deletions src/data-fixtures/Order/Order.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { test as base, expect } from '@playwright/test';
import type { FixtureTypes } from '../../types/FixtureTypes';
import type { components } from '@shopware/api-client/admin-api-types';
import type { Order } from '../../types/ShopwareTypes';
import {
getCurrency,
getSalutationId,
Expand Down Expand Up @@ -226,7 +226,7 @@ export const OrderData = base.extend<FixtureTypes>({

expect(orderResponse.ok()).toBeTruthy();

const { data: order } = (await orderResponse.json()) as { data: components['schemas']['Order'] };
const { data: order } = (await orderResponse.json()) as { data: Order };

// Use order data in the test
await use(order);
Expand Down
3 changes: 2 additions & 1 deletion src/data-fixtures/Product/DigitalProduct.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { test as base, expect } from '@playwright/test';
import type { FixtureTypes } from '../../types/FixtureTypes';
import type { Order } from '../../types/ShopwareTypes';
import type { components } from '@shopware/api-client/admin-api-types';

export const DigitalProductData = base.extend<FixtureTypes>({
Expand Down Expand Up @@ -58,7 +59,7 @@ export const DigitalProductData = base.extend<FixtureTypes>({
});
expect(orderSearchResponse.ok()).toBeTruthy();

const { data: ordersWithDigitalProduct } = (await orderSearchResponse.json()) as { data: components['schemas']['Order'][] };
const { data: ordersWithDigitalProduct } = (await orderSearchResponse.json()) as { data: Order[] };

// Delete Orders using the digital product, to be able to delete the uploaded media file
for (const order of ordersWithDigitalProduct) {
Expand Down
4 changes: 2 additions & 2 deletions src/data-fixtures/Product/Product.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { test as base, expect } from '@playwright/test';
import type { FixtureTypes } from '../../types/FixtureTypes';
import type { components } from '@shopware/api-client/admin-api-types';
import type { Product } from '../../types/ShopwareTypes';

export const ProductData = base.extend<FixtureTypes>({
ProductData: async ({ IdProvider, SalesChannelBaseConfig, AdminApiContext, DefaultSalesChannel }, use) => {
Expand Down Expand Up @@ -61,7 +61,7 @@ export const ProductData = base.extend<FixtureTypes>({
});
expect(productResponse.ok()).toBeTruthy();

const { data: product } = (await productResponse.json()) as { data: components['schemas']['Product'] };
const { data: product } = (await productResponse.json()) as { data: Product };

// Use product data in the test
await use(product);
Expand Down
5 changes: 3 additions & 2 deletions src/fixtures/DefaultSalesChannel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { test as base, expect, APIResponse } from '@playwright/test';
import type { FixtureTypes } from '../types/FixtureTypes';
import type { Customer } from '../types/ShopwareTypes';
import type { components } from '@shopware/api-client/admin-api-types';
import { createHash } from 'crypto';
import {
Expand Down Expand Up @@ -33,7 +34,7 @@ export interface DefaultSalesChannelTypes {
SalesChannelBaseConfig: StoreBaseConfig;
DefaultSalesChannel: {
salesChannel: components['schemas']['SalesChannel'];
customer: components['schemas']['Customer'] & { password: string };
customer: Customer;
url: string;
}
}
Expand Down Expand Up @@ -295,7 +296,7 @@ export const test = base.extend<NonNullable<unknown>, FixtureTypes>({
expect(themeAssignResp.ok()).toBeTruthy();
expect(salesChannelResp.ok()).toBeTruthy();

const customer = (await customerResp.json()) as { data: components['schemas']['Customer'] };
const customer = (await customerResp.json()) as { data: Customer };
const salesChannel = (await salesChannelResp.json()) as { data: components['schemas']['SalesChannel'] };

await use({
Expand Down
19 changes: 13 additions & 6 deletions src/page-objects/AdministrationPages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CustomerDetail } from './administration/CustomerDetail';
import { FirstRunWizard } from './administration/FirstRunWizard';
import { FlowBuilderCreate } from './administration/FlowBuilderCreate';
import { FlowBuilderListing } from './administration/FlowBuilderListing';
import { FlowBuilderDetail } from './administration/FlowBuilderDetail';
import { DataSharing } from './administration/DataSharing';
import { Dashboard } from './administration/Dashboard';

Expand All @@ -17,6 +18,7 @@ export interface AdministrationPageTypes {
AdminFirstRunWizard: FirstRunWizard;
AdminFlowBuilderCreate: FlowBuilderCreate;
AdminFlowBuilderListing: FlowBuilderListing;
AdminFlowBuilderDetail: FlowBuilderDetail;
AdminDataSharing: DataSharing;
AdminDashboard: Dashboard;
}
Expand All @@ -28,22 +30,23 @@ export const AdminPageObjects = {
FirstRunWizard,
FlowBuilderCreate,
FlowBuilderListing,
FlowBuilderDetail,
Dashboard,
DataSharing,
}

export const test = base.extend<FixtureTypes>({

AdminProductDetail: async ({ AdminPage, ProductData }, use) => {
await use(new ProductDetail(AdminPage, ProductData));
AdminProductDetail: async ({ AdminPage }, use) => {
await use(new ProductDetail(AdminPage));
},

AdminOrderDetail: async ({ AdminPage, OrderData }, use) => {
await use(new OrderDetail(AdminPage, OrderData));
AdminOrderDetail: async ({ AdminPage }, use) => {
await use(new OrderDetail(AdminPage));
},

AdminCustomerDetail: async ({ AdminPage, DefaultSalesChannel}, use) => {
await use(new CustomerDetail(AdminPage, DefaultSalesChannel.customer));
AdminCustomerDetail: async ({ AdminPage }, use) => {
await use(new CustomerDetail(AdminPage));
},

AdminFirstRunWizard: async ({ AdminPage }, use) => {
Expand All @@ -58,6 +61,10 @@ export const test = base.extend<FixtureTypes>({
await use(new FlowBuilderListing(AdminPage));
},

AdminFlowBuilderDetail: async ({ AdminPage }, use) => {
await use(new FlowBuilderDetail(AdminPage));
},

AdminDataSharing: async ({ AdminPage }, use) => {
await use(new DataSharing(AdminPage));
},
Expand Down
8 changes: 4 additions & 4 deletions src/page-objects/StorefrontPages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ export const test = base.extend<FixtureTypes>({
await use(new Home(StorefrontPage));
},

StorefrontProductDetail: async ({ StorefrontPage, ProductData }, use) => {
await use(new ProductDetail(StorefrontPage, ProductData));
StorefrontProductDetail: async ({ StorefrontPage }, use) => {
await use(new ProductDetail(StorefrontPage));
},

StorefrontCategory: async ({ StorefrontPage, CategoryData }, use) => {
await use(new Category(StorefrontPage, CategoryData));
StorefrontCategory: async ({ StorefrontPage }, use) => {
await use(new Category(StorefrontPage));
},

StorefrontCheckoutCart: async ({ StorefrontPage }, use) => {
Expand Down
12 changes: 3 additions & 9 deletions src/page-objects/administration/CustomerDetail.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import type { Page, Locator } from '@playwright/test';
import type { PageObject } from '../../types/PageObject';
import type { components } from '@shopware/api-client/admin-api-types';

export class CustomerDetail implements PageObject {
public readonly customerId;
public readonly customer: components['schemas']['Customer'];

public readonly editButton: Locator;
public readonly generalTab: Locator;
public readonly accountCard: Locator;

constructor(public readonly page: Page, customer: components['schemas']['Customer'] ) {
this.customerId = customer.id;
this.customer = customer;
constructor(public readonly page: Page) {
this.editButton = page.getByRole('button', { name: 'Edit' });
this.generalTab = page.getByRole('link', { name: 'General' });
this.accountCard = page.locator('.sw-customer-card')
}

async goTo() {
await this.page.goto(`#/sw/customer/detail/${this.customerId}/base`);
url(customerId: string) {
return `#/sw/customer/detail/${customerId}/base`
}
}
Loading
Loading