Skip to content

Commit

Permalink
Migrate channels tests to playwright (#4584)
Browse files Browse the repository at this point in the history
* channels tests migration

* change channels name

* Update rare-singers-cover.md

* type in input missing scroll into view on CI

* fix channel selection

* Trigger Build
  • Loading branch information
wojteknowacki committed Jan 3, 2024
1 parent 3b9f4ee commit 28a8f1c
Show file tree
Hide file tree
Showing 15 changed files with 240 additions and 25 deletions.
8 changes: 8 additions & 0 deletions .changeset/rare-singers-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"saleor-dashboard": minor
---

Tests migrated to playwright:
- Create basic channel;
- Edit channel settings to contain transaction flow, allow unpaid orders, authorize instead of charging, prio high stock;
- Delete channel
8 changes: 8 additions & 0 deletions playwright/data/e2eTestData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ export const CUSTOMER_ADDRESS = {
country: "Poland",
},
};
export const CHANNELS = {
channelToBeEditedSettings: {
id: "Q2hhbm5lbDoyMzkx",
},
channelToBeDeleted: {
name: "z - channel to be deleted",
},
};

export const PRODUCTS = {
singleProductType: {
Expand Down
97 changes: 88 additions & 9 deletions playwright/pages/channelsPage.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,94 @@
import type { Locator, Page } from "@playwright/test";
import { URL_LIST } from "@data/url";
import { DeleteChannelDialog } from "@dialogs/deleteChannelDialog";
import { RightSideDetailsPage } from "@pageElements/rightSideDetailsSection";
import { BasePage } from "@pages/basePage";
import { Page } from "@playwright/test";

export class ChannelPage {
export class ChannelPage extends BasePage {
readonly page: Page;
readonly createChannelButton: Locator;
readonly deleteChannelButton: Locator;
readonly channelsListTable: Locator;
readonly rightSideDetailsPage: RightSideDetailsPage;
readonly deleteChannelDialog: DeleteChannelDialog;

constructor(page: Page) {
constructor(
page: Page,
readonly deleteChannelButton = page.getByTestId("delete-channel"),
readonly channelRow = page.getByTestId("channel-row"),
readonly saveButton = page.getByTestId("button-bar-confirm"),
readonly createChannelButton = page.getByTestId("add-channel"),
readonly channelsListTable = page.getByTestId("channel-list"),
readonly channelNameInput = page.getByTestId("channel-name-input"),
readonly orderExpirationInput = page.getByTestId(
"delete-expired-order-input",
),
readonly transactionFlowCheckbox = page
.getByTestId("order-settings-mark-as-paid")
.locator("button")
.first(),
readonly allowUnpaidOrdersCheckbox = page
.getByTestId("allow-unpaid-orders-checkbox")
.locator("button")
.first(),
readonly authorizeInsteadOfChargingCheckbox = page
.getByTestId("default-transaction-strategy-checkbox")
.locator("button")
.first(),
readonly slugNameInput = page.getByTestId("slug-name-input"),
readonly channelCurrencySelect = page
.getByTestId("channel-currency-select-input")
.locator("input"),
readonly countrySelect = page
.getByTestId("country-select-input")
.locator("input"),
) {
super(page);
this.page = page;
this.deleteChannelButton = page.getByTestId("delete-channel");
this.createChannelButton = page.getByTestId("add-channel");
this.channelsListTable = page.getByTestId("channel-list");
this.rightSideDetailsPage = new RightSideDetailsPage(page);
this.deleteChannelDialog = new DeleteChannelDialog(page);
}

async clickAuthorizeInsteadOfChargingCheckbox() {
await this.authorizeInsteadOfChargingCheckbox.click();
}
async clickDeleteButtonOnRowContainingChannelName(channelName: string) {
await this.channelRow
.filter({ hasText: channelName })
.locator(this.deleteChannelButton)
.click();
}
async clickAllowUnpaidOrdersCheckbox() {
await this.allowUnpaidOrdersCheckbox.click();
}
async clickTransactionFlowCheckbox() {
await this.transactionFlowCheckbox.click();
}
async clickCreateChannelButton() {
await this.createChannelButton.click();
}
async clickSaveButton() {
await this.saveButton.click();
}
async typeChannelName(channelName = "z - automation") {
await this.channelNameInput.fill(channelName);
}
async typeSlugName(slugName: string) {
await this.slugNameInput.fill(slugName);
}
async typeOrderExpiration(expirationDays = "120") {
await this.orderExpirationInput.fill(expirationDays);
}
async selectCurrency(currencyName: string) {
await this.channelCurrencySelect.click();
await this.page.getByRole("option", { name: currencyName }).click();
}
async selectCountry(countryName: string) {
await this.countrySelect.click();
await this.page.getByRole("option", { name: countryName }).click();
}

async gotoChannelDetails(channelId: string) {
await this.page.goto(URL_LIST.channels + channelId);
}
async gotoChannelList() {
await this.page.goto(URL_LIST.channels);
}
}
5 changes: 5 additions & 0 deletions playwright/pages/configurationPage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { URL_LIST } from "@data/url";
import type { Locator, Page } from "@playwright/test";

export class ConfigurationPage {
Expand Down Expand Up @@ -67,4 +68,8 @@ export class ConfigurationPage {
async openAttributes() {
await this.attributesButton.click();
}

async gotoConfigurationView() {
await this.page.goto(URL_LIST.configuration);
}
}
4 changes: 2 additions & 2 deletions playwright/pages/dialogs/channelSelectDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export class ChannelSelectDialog {
async clickAllChannelsCheckbox() {
await this.allChannelsCheckbox.click();
}
async selectFirstChannel() {
async selectChannel(channelName: string) {
await this.displayedChannels
.first()
.filter({ hasText: channelName })
.locator(this.displayedChannelsCheckboxes)
.click();
}
Expand Down
18 changes: 18 additions & 0 deletions playwright/pages/dialogs/deleteChannelDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Locator, Page } from "@playwright/test";

export class DeleteChannelDialog {
readonly page: Page;

readonly deleteButton: Locator;

constructor(page: Page) {
this.page = page;

this.deleteButton = page.getByTestId("submit");
}

async clickDeleteButton() {
await this.deleteButton.first().click();
await this.deleteButton.waitFor({ state: "hidden" });
}
}
45 changes: 41 additions & 4 deletions playwright/pages/pageElements/rightSideDetailsSection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class RightSideDetailsPage {
readonly manageChannelsButton = page.getByTestId(
"channels-availability-manage-button",
),
readonly expandButton = page.getByTestId("expand-icon"),
readonly assignedChannels = page.getByTestId("channel-availability-item"),
readonly publishedRadioButtons = page.locator("[name*='isPublished'] > "),
readonly availableForPurchaseRadioButtons = page.locator(
Expand All @@ -57,11 +58,24 @@ export class RightSideDetailsPage {
readonly billingAddressSection = page.getByTestId(
"billing-address-section",
),
readonly warehousesSection = page.getByTestId("warehouses-section"),
readonly shippingZoneSection = page.getByTestId("shipping-zones-section"),
readonly editCustomerButton = page.getByTestId("edit-customer"),
readonly searchCustomerInput = page.getByTestId("select-customer"),
readonly selectCustomerOption = page.getByTestId(
"single-autocomplete-select-option",
),
readonly addShippingZonesButton = page.getByTestId("shipping-add-link"),
readonly addWarehousesButton = page.getByTestId("warehouse-add-link"),
readonly shippingZonesSelect = page.getByTestId(
"shipping-auto-complete-select",
),
readonly warehouseSelect = page.getByTestId(
"warehouse-auto-complete-select",
),
readonly allocationHighStockButton = page.getByTestId(
"PRIORITIZE_HIGH_STOCK",
),
) {
this.page = page;
this.channelSelectDialog = new ChannelSelectDialog(page);
Expand All @@ -70,6 +84,9 @@ export class RightSideDetailsPage {
async clickEditBillingAddressButton() {
await this.editBillingAddressButton.click();
}
async clickAllocationHighStockButton() {
await this.allocationHighStockButton.click();
}
async clickEditShippingAddressButton() {
await this.editShippingAddressButton.click();
}
Expand Down Expand Up @@ -122,24 +139,44 @@ export class RightSideDetailsPage {
async clickEditCustomerButton() {
await this.editCustomerButton.click();
}
async expandShippingZonesSection() {
await this.shippingZoneSection.locator(this.expandButton).click();
}
async expandWarehousesSection() {
await this.warehousesSection.locator(this.expandButton).click();
}

async clickSearchCustomerInput() {
await this.searchCustomerInput.click();
}
async clickAddShippingZonesButton() {
await this.addShippingZonesButton.click();
}
async clickAddWarehousesButton() {
await this.addWarehousesButton.click();
}
async selectShippingZone(zoneName = "Asia") {
await this.shippingZonesSelect.click();
await this.page.getByRole("option", { name: zoneName });
}
async selectWarehouse(warehouseName = "Asia") {
await this.warehouseSelect.click();
await this.page.getByRole("option", { name: warehouseName });
}

async selectCustomer(customer = "allison.freeman@example.com") {
await this.selectCustomerOption.locator(`text=${customer}`).click();
}

async selectOneChannelAsAvailableWhenMoreSelected() {
async selectOneChannelAsAvailableWhenMoreSelected(channel: string) {
await this.manageChannelsButton.click();
await this.channelSelectDialog.clickAllChannelsCheckbox();
await this.channelSelectDialog.selectFirstChannel();
await this.channelSelectDialog.selectChannel(channel);
await this.channelSelectDialog.clickConfirmButton();
}
async selectOneChannelAsAvailableWhenNoneSelected() {
async selectOneChannelAsAvailableWhenNoneSelected(channel: string) {
await this.manageChannelsButton.click();
await this.channelSelectDialog.selectFirstChannel();
await this.channelSelectDialog.selectChannel(channel);
await this.channelSelectDialog.clickConfirmButton();
await this.page.waitForLoadState("domcontentloaded");
}
Expand Down
7 changes: 4 additions & 3 deletions playwright/pages/vouchersPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,11 @@ export class VouchersPage extends BasePage {
channel = "Channel-PLN",
discountValue = "10",
) {
await this.valueSection
const valueInput = await this.valueSection
.getByTestId(channel)
.locator(this.discountValueInput)
.fill(discountValue);
.locator(this.discountValueInput);
await valueInput.scrollIntoViewIfNeeded();
await valueInput.fill(discountValue);
}
async typeMinimumOrderValue(
channel = "Channel-PLN",
Expand Down
50 changes: 50 additions & 0 deletions playwright/tests/channels.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { CHANNELS } from "@data/e2eTestData";
import { ChannelPage } from "@pages/channelsPage";
import { ConfigurationPage } from "@pages/configurationPage";
import { expect, test } from "@playwright/test";

test.use({ storageState: "playwright/.auth/admin.json" });
let configurationPage: ConfigurationPage;
let channelPage: ChannelPage;

test.beforeEach(({ page }) => {
configurationPage = new ConfigurationPage(page);
channelPage = new ChannelPage(page);
});

test("TC: SALEOR_97 Create basic channel @e2e @channels", async () => {
const slugName = new Date().toISOString();

await configurationPage.gotoConfigurationView();
await configurationPage.openChannels();
await channelPage.clickCreateChannelButton();
await channelPage.typeChannelName();
await channelPage.typeSlugName(slugName);
await channelPage.selectCurrency("AFN - Afghanistan");
await channelPage.selectCountry("Afghanistan");
await channelPage.clickSaveButton();
await channelPage.expectSuccessBanner();
});
test("TC: SALEOR_98 Edit channel settings to contain transaction flow, allow unpaid orders, authorize instead of charging, prio high stock @e2e @channels", async () => {
await channelPage.gotoChannelDetails(CHANNELS.channelToBeEditedSettings.id);
await channelPage.clickTransactionFlowCheckbox();
await channelPage.clickAllowUnpaidOrdersCheckbox();
await channelPage.clickAuthorizeInsteadOfChargingCheckbox();
await expect(channelPage.transactionFlowCheckbox).toBeChecked();
await expect(channelPage.authorizeInsteadOfChargingCheckbox).toBeChecked();
await expect(channelPage.allowUnpaidOrdersCheckbox).toBeChecked();
await channelPage.rightSideDetailsPage.clickAllocationHighStockButton();
await channelPage.clickSaveButton();
await channelPage.expectSuccessBanner();
});
test("TC: SALEOR_99 Delete channel @e2e @channels", async () => {
await channelPage.gotoChannelList();
await channelPage.clickDeleteButtonOnRowContainingChannelName(
CHANNELS.channelToBeDeleted.name,
);
await channelPage.deleteChannelDialog.clickDeleteButton();
await channelPage.expectSuccessBanner();
await expect(channelPage.channelsListTable).not.toContainText(
CHANNELS.channelToBeDeleted.name,
);
});
4 changes: 3 additions & 1 deletion playwright/tests/discountAndVouchers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ test("TC: SALEOR_85 Create voucher with manual code and percentage discount @vou
).toEqual(1);

await vouchersPage.clickPercentDiscountTypeButton();
await vouchersPage.rightSideDetailsPage.selectOneChannelAsAvailableWhenMoreSelected();
await vouchersPage.rightSideDetailsPage.selectOneChannelAsAvailableWhenMoreSelected(
"Channel-PLN",
);
await vouchersPage.typeDiscountValueInChannel("Channel-PLN", "50");

await vouchersPage.clickSaveButton();
Expand Down
12 changes: 8 additions & 4 deletions playwright/tests/product.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ test("TC: SALEOR_3 Create basic product with variants @e2e @product", async () =
});
test("TC: SALEOR_5 Create basic - single product type - product without variants @e2e @product", async () => {
await productPage.gotoCreateProductPage(PRODUCTS.singleProductType.id);
await productPage.rightSideDetailsPage.selectOneChannelAsAvailableWhenMoreSelected();
await productPage.rightSideDetailsPage.selectOneChannelAsAvailableWhenMoreSelected(
"Channel-PLN",
);
await productPage.typeNameDescAndRating();
await productPage.addSeo();
await productPage.addAllMetaData();
Expand All @@ -58,7 +60,7 @@ test("TC: SALEOR_26 Create basic info variant - via edit variant page @e2e @prod
await variantsPage.typeVariantName(variantName);
await variantsPage.clickMageChannelsButton();
await variantsPage.channelSelectDialog.clickAllChannelsCheckbox();
await variantsPage.channelSelectDialog.selectFirstChannel();
await variantsPage.channelSelectDialog.selectChannel("Channel-PLN");
await variantsPage.channelSelectDialog.clickConfirmButton();
await variantsPage.typeSellingPriceInChannel("PLN");
await variantsPage.typeCostPriceInChannel("PLN");
Expand All @@ -80,7 +82,7 @@ test("TC: SALEOR_27 Create full info variant - via edit variant page @e2e @produ
await variantsPage.typeVariantName(variantName);
await variantsPage.clickMageChannelsButton();
await variantsPage.channelSelectDialog.clickAllChannelsCheckbox();
await variantsPage.channelSelectDialog.selectFirstChannel();
await variantsPage.channelSelectDialog.selectChannel("Channel-PLN");
await variantsPage.channelSelectDialog.clickConfirmButton();
await variantsPage.selectFirstAttributeValue();
await variantsPage.typeCheckoutLimit();
Expand Down Expand Up @@ -142,7 +144,9 @@ test("TC: SALEOR_46 As an admin, I should be able to update a product by uploadi
await productPage.clickUploadMediaButton();
await productPage.uploadProductImage("beer.avif");
await productPage.productImage.waitFor({ state: "visible" });
await productPage.rightSideDetailsPage.selectOneChannelAsAvailableWhenNoneSelected();
await productPage.rightSideDetailsPage.selectOneChannelAsAvailableWhenNoneSelected(
"Channel-PLN",
);

await productPage.selectFirstTaxOption();
const preSaveTax = await productPage.rightSideDetailsPage.taxInput
Expand Down
2 changes: 2 additions & 0 deletions src/channels/components/ChannelForm/ChannelForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,11 @@ export const ChannelForm: React.FC<ChannelFormProps> = ({
name="name"
value={data.name}
onChange={onChange}
data-test-id="channel-name-input"
/>
<FormSpacer />
<Input
data-test-id="slug-name-input"
error={!!formErrors.slug}
helperText={getChannelsErrorMessage(formErrors?.slug, intl)}
disabled={disabled}
Expand Down
Loading

0 comments on commit 28a8f1c

Please sign in to comment.