Skip to content

Commit

Permalink
add(test): add tests for import export account (#209)
Browse files Browse the repository at this point in the history
  • Loading branch information
luisecm authored Dec 30, 2024
1 parent d1df66d commit 45f9f13
Show file tree
Hide file tree
Showing 12 changed files with 547 additions and 13 deletions.
10 changes: 10 additions & 0 deletions playwright/PageObjects/CreateOrImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type Locator, type Page } from "@playwright/test";

export class CreateOrImportPage extends MainPage {
readonly buttonCreateAccount: Locator;
readonly buttonImportAccount: Locator;
readonly labelCreateTitle: Locator;
readonly textCreateDescription: Locator;

Expand All @@ -12,6 +13,7 @@ export class CreateOrImportPage extends MainPage {
) {
super(page, viewport);
this.buttonCreateAccount = this.page.getByTestId("button-create-account");
this.buttonImportAccount = this.page.getByTestId("button-import-account");
this.labelCreateTitle = this.page.getByTestId("label-create-title");
this.textCreateDescription = this.page.getByTestId(
"text-create-description",
Expand All @@ -22,7 +24,15 @@ export class CreateOrImportPage extends MainPage {
await this.buttonCreateAccount.click();
}

async clickImportAccount() {
await this.buttonImportAccount.click();
}

async navigateTo() {
await this.page.goto("/");
}

async validatePageIsDisplayed() {
await this.labelCreateTitle.waitFor({ state: "attached" });
}
}
159 changes: 159 additions & 0 deletions playwright/PageObjects/ImportAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import MainPage from "./MainPage";
import { expect, type Locator, type Page } from "@playwright/test";
import { readFile } from "fs/promises";

export class ImportAccountPage extends MainPage {
readonly buttonGoBack: Locator;
readonly buttonImportAccountFromFile: Locator;
readonly buttonImportAccountFromRemote: Locator;
readonly buttonUploadPassphrase: Locator;
readonly textImportAccountSecondary: Locator;
readonly titleImportAccount: Locator;

constructor(
public readonly page: Page,
public readonly viewport: string,
) {
super(page, viewport);
this.buttonGoBack = this.page.getByTestId("button-import-account-go-back");
this.buttonImportAccountFromFile = this.page.getByTestId(
"import-account-file",
);
this.buttonImportAccountFromRemote =
this.page.getByTestId("import-account");
this.buttonUploadPassphrase = this.page.getByTestId("upload-passphrase");
this.textImportAccountSecondary = this.page.getByTestId(
"text-import-account-secondary",
);
this.titleImportAccount = this.page.getByTestId("title-import-account");
}

async clickOnGoBack() {
await this.buttonGoBack.click();
}

async clickOnImportAccountFromFile() {
await this.buttonImportAccountFromFile.click();
}

async clickOnImportAccountFromRemote() {
await this.buttonImportAccountFromRemote.click();
}

async clickOnUploadPassphrase() {
await this.buttonUploadPassphrase.click();
}

async enterSeedPhraseManually(seedPhrase: string[]) {
// Loop through each of the 12 input fields
for (let i = 1; i <= 12; i++) {
// Get the text from the array element and type it on input field
await this.page
.locator(`[data-cy="ordered-phrase-word-${i}"]`)
.locator("input")
.fill(seedPhrase[i - 1]);
}
}

async getRecoveryPhrase() {
let phrase = [];

// Loop through each of the 12 phrases
for (let i = 1; i <= 12; i++) {
// Ensure the phrase number element exists
await this.page
.locator(`[data-cy="ordered-phrase-number-${i}"]`)
.waitFor({ state: "attached" });

// Ensure the phrase word element exists
await this.page
.locator(`[data-cy="ordered-phrase-word-${i}"]`)
.waitFor({ state: "attached" });

// Get the text from the <p> tag inside the phrase word element
const text = await this.page
.locator(`[data-cy="ordered-phrase-word-${i}"]`)
.locator("p")
.innerText();
phrase.push(text);
}

return phrase;
}

async getNumberOfSeedWordsDisplayed() {
const count = await this.page
.locator(`[data-cy^="ordered-phrase-word-`)
.count();
return count;
}

async importAccountFromFile(
phraseType: "file" | "manual",
backUpFile: string,
seedPhrasePath?: string,
seedPhrase?: string[],
) {
if (phraseType === "file") {
await this.uploadSeedPhraseFile(seedPhrasePath);
} else if (phraseType === "manual") {
await this.enterSeedPhraseManually(seedPhrase);
} else {
throw new Error("Invalid passphrase type");
}
await this.uploadImportedFile(backUpFile);
}

async importAccountFromRemote(
phraseType: "file" | "manual",
seedPhrasePath?: string,
seedPhrase?: string[],
) {
if (phraseType === "file") {
await this.uploadSeedPhraseFile(seedPhrasePath);
} else if (phraseType === "manual") {
await this.enterSeedPhraseManually(seedPhrase);
} else {
throw new Error("Invalid passphrase type");
}
await this.clickOnImportAccountFromRemote();
}

async readRecoveryPhraseFile(filePath: string) {
const fileContent = await readFile(filePath, "utf-8");
const fileSeedPhraseArray = fileContent.split(/\s+/).filter(Boolean);
return fileSeedPhraseArray;
}

async uploadImportedFile(filePath: string) {
const fileChooserPromise = this.page.waitForEvent("filechooser");
await this.clickOnImportAccountFromFile();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(filePath);
}

async uploadSeedPhraseFile(filePath: string) {
const fileChooserPromise = this.page.waitForEvent("filechooser");
await this.clickOnUploadPassphrase();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(filePath);
}

async validateToastInvalidPhrase() {
await this.toastNotificationText.waitFor({ state: "attached" });
await expect(this.toastNotificationText).toHaveText(
"Invalid word in phrase",
);
}

async validateToastUnkwnownError() {
await this.toastNotificationText.waitFor({ state: "attached" });
await expect(this.toastNotificationText).toHaveText(
"An unknown error occurred",
);
}

async validatePageIsLoaded() {
await this.titleImportAccount.waitFor({ state: "attached" });
}
}
4 changes: 4 additions & 0 deletions playwright/PageObjects/LoginPin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export class LoginPinPage extends MainPage {
readonly buttonCreateNewProfile: Locator;
readonly buttonPinSettings: Locator;
readonly labelChooseEnterPin: Locator;
readonly oldAccountToBeOverwrittenText: Locator;
readonly pinButton0: Locator;
readonly pinButton1: Locator;
readonly pinButton2: Locator;
Expand Down Expand Up @@ -39,6 +40,9 @@ export class LoginPinPage extends MainPage {
);
this.buttonPinSettings = this.page.getByTestId("button-settings");
this.labelChooseEnterPin = this.page.getByTestId("label-choose-enter-pin");
this.oldAccountToBeOverwrittenText = this.page.getByText(
"By continuing your old account will be overwritten!",
);
this.pinButton0 = this.page.getByTestId("button-pin-0");
this.pinButton1 = this.page.getByTestId("button-pin-1");
this.pinButton2 = this.page.getByTestId("button-pin-2");
Expand Down
7 changes: 7 additions & 0 deletions playwright/PageObjects/MainPage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { expect, type Locator, type Page } from "@playwright/test";
import { readFile } from "fs/promises";
const fs = require("fs");
const path = require("path");
export default class MainPage {
Expand Down Expand Up @@ -288,6 +289,12 @@ export default class MainPage {
});
}

async readRecoveryPhraseFile(filePath: string) {
const fileContent = await readFile(filePath, "utf-8");
const fileSeedPhraseArray = fileContent.split(/\s+/).filter(Boolean);
return fileSeedPhraseArray;
}

async validateNoFavoritesAreVisible() {
await this.clickOnShowSidebarIfClosed();
await this.favoriteCircle.waitFor({ state: "detached" });
Expand Down
9 changes: 1 addition & 8 deletions playwright/PageObjects/SaveRecoverySeed.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import MainPage from "./MainPage";
import { expect, type Locator, type Page } from "@playwright/test";
import { readFile } from "fs/promises";
import { type Locator, type Page } from "@playwright/test";

export class SaveRecoverySeedPage extends MainPage {
readonly buttonDownloadPhrase: Locator;
Expand Down Expand Up @@ -58,12 +57,6 @@ export class SaveRecoverySeedPage extends MainPage {
return count;
}

async readRecoveryPhraseFile(filePath: string) {
const fileContent = await readFile(filePath, "utf-8");
const fileSeedPhraseArray = fileContent.split(/\s+/).filter(Boolean);
return fileSeedPhraseArray;
}

async saveRecoverySeed() {
// Wait for the download event
const filename = "seed-phrase.txt";
Expand Down
60 changes: 58 additions & 2 deletions playwright/PageObjects/Settings/SettingsProfile.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { expect, type Locator, type Page } from "@playwright/test";
import { SettingsBase } from "./SettingsBase";
const fs = require("fs");
const path = require("path");

export class SettingsProfile extends SettingsBase {
readonly accountIntegrations: Locator;
Expand Down Expand Up @@ -37,6 +39,11 @@ export class SettingsProfile extends SettingsBase {
readonly deleteAccountSectionButton: Locator;
readonly deleteAccountSectionLabel: Locator;
readonly deleteAccountSectionText: Locator;
readonly exportAccountSection: Locator;
readonly exportAccountSectionLabel: Locator;
readonly exportAccountSectionText: Locator;
readonly exportAccountSectionFileButton: Locator;
readonly exportAccountSectionRemoteButton: Locator;
readonly identiconSettingsProfile: Locator;
readonly inputSettingsProfileShortID: Locator;
readonly inputSettingsProfileShortIDGroup: Locator;
Expand Down Expand Up @@ -201,6 +208,18 @@ export class SettingsProfile extends SettingsBase {
this.deleteAccountSectionText = this.deleteAccountSection.getByTestId(
"setting-section-text",
);
this.exportAccountSection = this.page.getByTestId("export-account");
this.exportAccountSectionLabel = this.exportAccountSection.getByTestId(
"setting-section-label",
);
this.exportAccountSectionText = this.exportAccountSection.getByTestId(
"setting-section-text",
);
this.exportAccountSectionFileButton = this.exportAccountSection.getByTestId(
"export-account-file",
);
this.exportAccountSectionRemoteButton =
this.exportAccountSection.getByTestId("export-account-remote");
this.identiconSettingsProfile = this.page
.locator(".identicon")
.locator("img");
Expand Down Expand Up @@ -329,12 +348,39 @@ export class SettingsProfile extends SettingsBase {
);
}

// Rewrite everything here in playwright

async copyShortID() {
await this.inputSettingsProfileShortIDGroup.click();
}

async deleteAccount() {
await this.deleteAccountSectionButton.click();
}

async exportAccountToFile() {
const downloadPath = path.join(__dirname, "downloads");
if (!fs.existsSync(downloadPath)) {
fs.mkdirSync(downloadPath);
}

const downloadPromise = this.page.waitForEvent("download");
await this.exportAccountSectionFileButton.click();
const download = await downloadPromise;

const fileName = download.suggestedFilename(); // Get the suggested filename
const filePath = path.join(downloadPath, fileName);
await download.saveAs(filePath); // Save the file to the designated path

// Validate the downloaded file
expect(fs.existsSync(filePath)).toBeTruthy(); // Check file exists
expect([".upk"]).toContain(path.extname(fileName)); // Validate file extension
}

async exportAccountToRemote() {
await this.exportAccountSectionRemoteButton.click();
await this.validateToastSuccessRemoteExport();
await this.waitForToastNotificationToDisappear();
}

async getProfileIdenticonSource() {
const source = await this.identiconSettingsProfile.getAttribute("src");
return source;
Expand Down Expand Up @@ -517,6 +563,16 @@ export class SettingsProfile extends SettingsBase {
await expect(this.toastNotificationText).toHaveText("Profile Updated!");
}

async validateToastSuccessRemoteExport() {
await this.toastNotification.waitFor({ state: "attached" });
const textToast = this.toastNotification.getByText(
"Successfully exported account to remote",
);
await expect(textToast).toHaveText(
"Successfully exported account to remote",
);
}

async uploadProfileBanner(file: string) {
await this.profileBanner.click();
await this.profileBannerInput.setInputFiles(file);
Expand Down
Binary file added playwright/PageObjects/Settings/downloads/export.upk
Binary file not shown.
Binary file added playwright/assets/export.upk
Binary file not shown.
1 change: 1 addition & 0 deletions playwright/assets/seed-phrase.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shoe enough industry soft unit dilemma slight venture mirror man nice motion
2 changes: 1 addition & 1 deletion playwright/specs/01-pin-input.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ test.describe("Create Account and Login Tests", () => {
const saveRecoverySeed = new SaveRecoverySeedPage(page, viewport);

await test.step("Validate Create or Import Page and then click on Create New Account", async () => {
await createOrImport.labelCreateTitle.waitFor({ state: "attached" });
await createOrImport.validatePageIsDisplayed();
await expect(createOrImport.labelCreateTitle).toHaveText(
"Account Creation",
);
Expand Down
Loading

0 comments on commit 45f9f13

Please sign in to comment.