Skip to content

Commit

Permalink
Migrated taxes tests (#4628)
Browse files Browse the repository at this point in the history
* taxes tests

* Create rude-clocks-attack.md

* change locator for checkbox in exception country list

* Trigger Build

* locator fix

* changed test name

* Update rude-clocks-attack.md
  • Loading branch information
wojteknowacki committed Jan 24, 2024
1 parent 4d82f8f commit 6f6e5ef
Show file tree
Hide file tree
Showing 18 changed files with 345 additions and 6 deletions.
9 changes: 9 additions & 0 deletions .changeset/rude-clocks-attack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"saleor-dashboard": minor
---

Migrated taxes tests:
- Change taxes in channel to use tax app
- Change taxes in channel: enter prices without tax, do not show gross price, add country exception
- Add new country and tax rates to it
- Add new class with metadata and set tax rate for single country
19 changes: 19 additions & 0 deletions playwright/data/e2eTestData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,32 @@ export const COLLECTIONS = {
names: ["Collection to be deleted 1/2", "Collection to be deleted 2/2"],
},
};
export const COUNTRIES = {
afghanistan: {
countryCode: "AF",
name: "Afghanistan",
},
albania: {
countryCode: "AL",
name: "Albania",
},
countryToBeAddedInTaxes: {
name: "Bosnia and Herzegovina",
},
};
export const CHANNELS = {
channelToBeEditedSettings: {
id: "Q2hhbm5lbDoyMzkx",
},
channelToBeDeleted: {
name: "z - channel to be deleted",
},
channelForTaxEdition: {
name: "a channel for tax tests",
},
plnChannel: {
id: "VGF4Q29uZmlndXJhdGlvbjox",
},
};
export const GIFT_CARDS = {
giftCardToBeEdited: {
Expand Down
2 changes: 2 additions & 0 deletions playwright/data/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export const URL_LIST = {
vouchers: "discounts/vouchers/",
vouchersAddPage: "discounts/vouchers/add",
variant: "variant/",
taxChannel: "taxes/channels/",
taxCountry: "taxes/countries/",
warehouses: "warehouses/",
webhooksAndEvents: "custom-apps/",
resetPassword: "new-password/?email=",
Expand Down
3 changes: 3 additions & 0 deletions playwright/pages/configurationPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export class ConfigurationPage {
async openShippingMethods() {
await this.shippingMethodsButton.click();
}
async openTaxes() {
await this.taxesButton.click();
}
async openChannels() {
await this.channelsButton.click();
}
Expand Down
30 changes: 30 additions & 0 deletions playwright/pages/dialogs/addCountriesDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Page } from "@playwright/test";

export class AddCountriesDialog {
readonly page: Page;

constructor(
page: Page,
readonly searchCountryInput = page
.getByTestId("search-country-input")
.locator("input"),
readonly countryRow = page.getByTestId("country-row"),
readonly addButton = page.getByTestId("add-button"),
readonly rowRadioButton = page.locator("input[type='radio']"),
) {
this.page = page;
}

async typeSearchedCountry(countryName = "Canada") {
await this.searchCountryInput.fill(countryName);
}

async checkAndSaveSingleCountry(countryName = "Canada") {
await this.countryRow
.filter({ hasText: countryName })
.locator(this.rowRadioButton)
.click();
await this.addButton.click();
await this.countryRow.first().waitFor({ state: "hidden" });
}
}
160 changes: 160 additions & 0 deletions playwright/pages/taxesPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { CHANNELS } from "@data/e2eTestData";
import { URL_LIST } from "@data/url";
import { AddCountriesDialog } from "@dialogs/addCountriesDialog";
import { MetadataSeoPage } from "@pageElements/metadataSeoPage";
import { BasePage } from "@pages/basePage";
import type { Page } from "@playwright/test";

export class TaxesPage extends BasePage {
readonly page: Page;
readonly addCountriesDialog: AddCountriesDialog;
readonly metadataSeoPage: MetadataSeoPage;

constructor(
page: Page,
readonly appOrFlatRateSelect = page
.getByTestId("app-flat-select")
.locator("[role='button']"),
readonly chanelListRow = page.getByTestId("channels-list-rows"),
readonly countriesListRow = page.getByTestId("countries-list-rows"),
readonly classListRow = page.getByTestId("class-list-rows"),
readonly countriesTab = page.getByTestId("countries-tab"),
readonly taxClassTab = page.getByTestId("tax-classes-tab"),
readonly enteredRenderedSection = page.getByTestId(
"entered-rendered-prices-section",
),
readonly pricesEnteredWithTaxButton = page.locator(
"[name='pricesEnteredWithTax'][ value='true']",
),
readonly pricesEnteredWithoutTaxButton = page.locator(
"[name='pricesEnteredWithTax'][ value='false']",
),
readonly displayGrossPricesCheckbox = page.locator(
"[name='displayGrossPrices']",
),
readonly addCountryButton = page.getByTestId("add-country-button"),
readonly createClassButton = page.getByTestId("create-class-button"),
readonly saveButton = page.getByTestId("button-bar-confirm"),
readonly exceptionCountryRows = page.getByTestId("exception-country"),
readonly exceptionCountryGrossPriceCheckbox = page.getByTestId(
"display-gross-prices-checkbox",
),
readonly checkBoxCheckedState = page.locator("Mui-checked"),
readonly exceptionCountriesCheckBoxCheckedState = page.locator(
"[class*='Mui-checked']",
),
readonly searchTaxClassInput = page
.getByTestId("search-tax-class-input")
.locator("input"),
readonly searchedCountryRows = page.getByTestId("country-rows"),

readonly searchTaxCountryInput = page
.getByTestId("search-tax-countries-input")
.locator("input"),
readonly taxClassNameInput = page
.getByTestId("class-name-input")
.locator("input"),
readonly noTaxRateInput = page.getByTestId("No Taxes").locator("input"),
readonly defaultRateInput = page
.getByTestId("Country default rate")
.locator("input"),
readonly audioProductsRateInput = page
.getByTestId("Audio Products (tapes, cds etc.)")
.locator("input"),
readonly dataServicesRateInput = page
.getByTestId("Data services - storage and retrieval ")
.locator("input"),
readonly standardRateInput = page.getByTestId("standard").locator("input"),
readonly temporaryUnmappedRateInput = page
.getByTestId("Temporary Unmapped Other SKU - taxable default")
.locator("input"),
) {
super(page);
this.page = page;
this.addCountriesDialog = new AddCountriesDialog(page);
this.metadataSeoPage = new MetadataSeoPage(page);
}

async clickSelectMethodField() {
await this.appOrFlatRateSelect.click();
}
async typeAllTaxRatesForCountry(
defaultRate: string,
noTaxRate: string,
audioRate: string,
dataServiceRate: string,
standardRate: string,
temporaryRate: string,
) {
await this.defaultRateInput.fill(defaultRate);
await this.audioProductsRateInput.fill(audioRate);
await this.dataServicesRateInput.fill(dataServiceRate);
await this.noTaxRateInput.fill(noTaxRate);
await this.standardRateInput.fill(standardRate);
await this.temporaryUnmappedRateInput.fill(temporaryRate);
}
async clickCountriesTab() {
await this.countriesTab.click();
await this.countriesListRow.first().waitFor({ state: "visible" });
}
async clickTaxClassTab() {
await this.taxClassTab.click();
await this.classListRow.first().waitFor({ state: "visible" });
}
async clickCountryFromList(countryCode: string) {
await this.countriesListRow.filter({ hasText: countryCode }).click();
}
async clickSaveButton() {
await this.saveButton.click();
}
async typeTaxClassName(taxClassName: string) {
await this.taxClassNameInput.fill(taxClassName);
}
async typeSearchedTaxCountryName(taxCountryName: string) {
await this.searchTaxCountryInput.fill(taxCountryName);
}
async typeTaxRateInSearchedCountryRow(
taxCountryName: string,
taxRateValue: string,
) {
await this.searchedCountryRows
.filter({ hasText: taxCountryName })
.locator("input")
.fill(taxRateValue);
}
async clickCreateClassButton() {
await this.createClassButton.click();
}

async selectTaxCalculationMethod(method: "FLAT_RATES" | "TAX_APP") {
await this.clickSelectMethodField();
await this.page.getByTestId(`select-field-option-${method}`).click();
}

async selectPricesWithoutTaxes() {
await this.enteredRenderedSection
.locator(this.pricesEnteredWithoutTaxButton)
.click();
}
async selectPricesWithTaxes() {
await this.enteredRenderedSection
.locator(this.pricesEnteredWithTaxButton)
.click();
}
async clickShowGrossPricesInStorefront() {
await this.enteredRenderedSection
.locator(this.displayGrossPricesCheckbox)
.click();
}

async clickAddCountryButton() {
await this.addCountryButton.click();
}
async selectChannel(channelName: string) {
await this.chanelListRow.filter({ hasText: channelName }).click();
}

async gotoChannelsTabUrl() {
await this.page.goto(URL_LIST.taxChannel + CHANNELS.plnChannel.id);
}
}
2 changes: 1 addition & 1 deletion playwright/tests/channels.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ test("TC: SALEOR_97 Create basic channel @e2e @channels", async () => {
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 () => {
test("TC: SALEOR_98 Edit channel - transaction flow, allow unpaid, authorize, prio high stock @e2e @channels", async () => {
await channelPage.gotoChannelDetails(CHANNELS.channelToBeEditedSettings.id);
await channelPage.clickTransactionFlowCheckbox();
await channelPage.clickAllowUnpaidOrdersCheckbox();
Expand Down
77 changes: 77 additions & 0 deletions playwright/tests/taxes.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { CHANNELS, COUNTRIES } from "@data/e2eTestData";
import { ConfigurationPage } from "@pages/configurationPage";
import { TaxesPage } from "@pages/taxesPage";
import { expect, test } from "@playwright/test";

test.use({ storageState: "playwright/.auth/admin.json" });

let configurationPage: ConfigurationPage;
let taxesPage: TaxesPage;

test.beforeEach(({ page }) => {
configurationPage = new ConfigurationPage(page);
taxesPage = new TaxesPage(page);
});

test("TC: SALEOR_115 Change taxes in channel to use tax app @taxes @e2e", async () => {
await configurationPage.gotoConfigurationView();
await configurationPage.openTaxes();
await taxesPage.selectChannel(CHANNELS.channelForTaxEdition.name);
await taxesPage.selectTaxCalculationMethod("TAX_APP");
await taxesPage.clickSaveButton();
await taxesPage.expectSuccessBanner();
});
test("TC: SALEOR_116 Change taxes in channel: enter prices without tax, do not show gross price, add country exception @taxes @e2e", async () => {
await taxesPage.gotoChannelsTabUrl();
await taxesPage.selectChannel(CHANNELS.channelForTaxEdition.name);

await taxesPage.selectPricesWithoutTaxes();
await taxesPage.clickShowGrossPricesInStorefront();
await taxesPage.clickAddCountryButton();
await taxesPage.addCountriesDialog.typeSearchedCountry("Canada");
await taxesPage.addCountriesDialog.checkAndSaveSingleCountry("Canada");
await expect(taxesPage.exceptionCountryRows).toContainText("Canada");
expect(
await taxesPage.exceptionCountryRows
.locator(taxesPage.exceptionCountriesCheckBoxCheckedState)
.count(),
).toEqual(1);
await taxesPage.clickSaveButton();
await taxesPage.expectSuccessBanner();
});

test("TC: SALEOR_117 Add new country and tax rates to it @taxes @e2e", async () => {
await taxesPage.gotoChannelsTabUrl();
await taxesPage.clickCountriesTab();
await taxesPage.clickAddCountryButton();
await taxesPage.addCountriesDialog.typeSearchedCountry(
COUNTRIES.countryToBeAddedInTaxes.name,
);

await taxesPage.addCountriesDialog.checkAndSaveSingleCountry(
COUNTRIES.countryToBeAddedInTaxes.name,
);
expect(await taxesPage.countriesListRow.first()).toHaveText(
COUNTRIES.countryToBeAddedInTaxes.name,
);
await taxesPage.typeAllTaxRatesForCountry("23", "0", "16", "7", "21", "19");
await taxesPage.clickSaveButton();
await taxesPage.expectSuccessBanner();
});

test("TC: SALEOR_118 Add new class with metadata and set tax rate for single country @taxes @e2e", async () => {
await taxesPage.gotoChannelsTabUrl();
await taxesPage.clickTaxClassTab();
await taxesPage.clickCreateClassButton();
expect(await taxesPage.taxClassNameInput).toHaveValue("New tax class");

await taxesPage.typeTaxClassName("Automation test tax class");
await taxesPage.typeSearchedTaxCountryName("United States of America");
await taxesPage.typeTaxRateInSearchedCountryRow(
"United States of America",
"20",
);
await taxesPage.metadataSeoPage.expandAndAddAllMetadata();
await taxesPage.clickSaveButton();
await taxesPage.expectSuccessBanner();
});
3 changes: 3 additions & 0 deletions src/taxes/components/TaxCountryDialog/TaxCountryDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const TaxCountryDialog: React.FC<TaxCountryDialogProps> = ({
</DialogHeader>
<DialogContent className={classes.wrapper}>
<TextField
data-test-id="search-country-input"
value={query}
onChange={e => setQuery(e.target.value)}
variant="outlined"
Expand All @@ -80,6 +81,7 @@ export const TaxCountryDialog: React.FC<TaxCountryDialogProps> = ({
{filteredCountries.map(country => (
<React.Fragment key={country.code}>
<FormControlLabel
data-test-id="country-row"
label={country.country}
checked={country.code === selectedCountry?.code}
onChange={() => setSelectedCountry(country)}
Expand All @@ -92,6 +94,7 @@ export const TaxCountryDialog: React.FC<TaxCountryDialogProps> = ({
</DialogContent>
<DialogActions>
<Button
data-test-id="add-button"
variant="primary"
onClick={() => {
onConfirm(selectedCountry);
Expand Down
1 change: 1 addition & 0 deletions src/taxes/components/TaxInput/TaxInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const TaxInput: React.FC<TaxInputProps> = ({

return (
<TextField
data-test-id="tax-input"
type="number"
fullWidth
placeholder={placeholder}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const TaxChannelsMenu: React.FC<TaxChannelsMenuProps> = ({
{configurations?.map((configuration, confIndex) => (
<React.Fragment key={configuration.id}>
<ListItemLink
data-test-id="channels-list-rows"
className={clsx(classes.clickable, classes.tableRow, {
[classes.selected]:
configuration.id === selectedConfigurationId,
Expand Down
Loading

0 comments on commit 6f6e5ef

Please sign in to comment.