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

Migrated taxes tests #4628

Merged
merged 9 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
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": minot
---

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" });
}
}
157 changes: 157 additions & 0 deletions playwright/pages/taxesPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
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("[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);
}
}
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.checkBoxCheckedState)
.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
4 changes: 4 additions & 0 deletions src/taxes/pages/TaxChannelsPage/TaxChannelsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,17 @@ export const TaxChannelsPage: React.FC<TaxChannelsPageProps> = props => {
<PageTab
label={intl.formatMessage(taxesMessages.channelsSection)}
value="channels"
data-test-id="channels-tab"
/>
<PageTab
label={intl.formatMessage(taxesMessages.countriesSection)}
value="countries"
data-test-id="countries-tab"
/>
<PageTab
label={intl.formatMessage(taxesMessages.taxClassesSection)}
value="tax-classes"
data-test-id="tax-classes-tab"
/>
</PageTabs>
<VerticalSpacer spacing={2} />
Expand All @@ -206,6 +209,7 @@ export const TaxChannelsPage: React.FC<TaxChannelsPageProps> = props => {
)}
toolbar={
<Button
data-test-id="add-country-button"
variant="secondary"
onClick={() => openDialog("add-country")}
>
Expand Down
Loading
Loading