Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/buildAndDeploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ jobs:
concurrency:
group: build-and-deploy
cancel-in-progress: true
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20

- name: Install dependencies
run: npm ci
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/checkPullRequests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ jobs:
concurrency:
group: ${{ github.head_ref }}
cancel-in-progress: true
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20

- name: Install dependencies
run: npm ci
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/makeArtifactWithTestScreenshots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: "Make artifact with Test Screenshots"

on: workflow_dispatch

jobs:
make_artifact_with_test_screenshots:
name: Make artifact with Test Screenshots
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 20

- name: Install dependencies
run: npm ci

- name: Install Playwright Browsers
run: npx playwright install --with-deps

- name: Run e2e tests
run: PLAYWRIGHT_DEV_SERVER=1 npm run test:e2e:update-snapshots

- name: Upload test screenshots
uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: test-screenshots
path: ./e2e/vue.spec.ts-snapshots
retention-days: 1
2 changes: 1 addition & 1 deletion e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"extends": "@vue/tsconfig/tsconfig.node.json",
"extends": "@vue/tsconfig/tsconfig.json",
"include": ["./**/*"]
}
135 changes: 135 additions & 0 deletions e2e/vue.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,138 @@ test("visits the app root url", async ({ page }) => {
await page.goto("/");
await expect(page.locator("h1")).toHaveText("Get Crypto Address");
});

test("check menu items", async ({ page }) => {
await page.goto("/");
const $menu = page.locator('[data-test-id="page-header-menu"]');
const menuItems = $menu.getByRole("menuitem");
const $$menuItems = await menuItems.all();
await expect(menuItems).toHaveCount(4);

await expect($$menuItems[0]).toHaveText("Home");
await expect($$menuItems[1]).toHaveText("Create Crypto Address");
await expect($$menuItems[2]).toHaveText("Create Paper Wallet");
await expect($$menuItems[3]).toHaveText("Paper Wallet Editor");
});

test("General flow", async ({ page, context, browserName }) => {
if (browserName === "chromium") {
await context.grantPermissions(["clipboard-read", "clipboard-write"]);
}

await page.goto("/");
await page.getByRole("link", { name: "Create Crypto Address" }).click();
await page.waitForURL("/create-wallets/", { timeout: 1000 });

// Check the default count of addresses
{
const $counter = page.locator('[data-test-id="input-count-tokens"] input');
const count = await $counter.inputValue();
expect(count).toBe("20");
}

// Generate new addresses
await page.getByRole("button", { name: "Generate new addresses" }).click();

// Check the count of generated addresses
const $addresses = page.locator('[data-test-el="key-address-item"]');
await $addresses.first().waitFor({ state: "visible", timeout: 5000 });
expect(await $addresses.count()).toBe(20);

/// Check the first address
const $firstAddress = $addresses.first();
const privateKey = await $firstAddress
.locator('[data-test-el="private-key"]')
.innerText();
const address = await $firstAddress
.locator('[data-test-el="address"]')
.innerText();

// Copy the first address
if (browserName !== "webkit") {
const $copyButton = $firstAddress.locator(
'[data-test-id="button-copy-wallet-to-clipboard"]',
);
await $copyButton.click();
const handle = await page.evaluateHandle(() =>
navigator.clipboard.readText(),
);
const clipboardContent = await handle.jsonValue();
expect(clipboardContent).toEqual(`${privateKey}:${address}`);
}

// Modal with the address
{
const $openModalButton = $firstAddress.locator(
'[data-test-el="button-show-qr-codes"]',
);
await $openModalButton.click();
const $modal = page.getByRole("dialog");
await $modal.waitFor({ state: "visible", timeout: 1000 });
const $modalSecret = $modal.locator(
'[data-test-id="dialog-qr-code-secret"] .n-thing-main__description',
);
const $modalAddress = $modal.locator(
'[data-test-id="dialog-qr-code-address"] .n-thing-main__description',
);
expect(await $modalSecret.innerText()).toBe(privateKey);
expect(await $modalAddress.innerText()).toBe(address);
const $modalMask = page.locator(".n-modal-mask");
await page.mouse.click(1, 1);
await $modalMask.waitFor({ state: "detached", timeout: 1000 });
}

/// Paper wallet page
const $manualSecret = page.locator(
'[data-test-id="input-manual-secret"] textarea',
);
const $manualAddress = page.locator(
'[data-test-id="input-manual-address"] textarea',
);
// validate provided address and secret
{
const $printButton = $firstAddress.locator(
'[data-test-el="button-generate-paper-wallet"]',
);
await $printButton.click();
await page.waitForURL("/paper-wallets/");
const $manualSecret = page.locator(
'[data-test-id="input-manual-secret"] textarea',
);
const $manualAddress = page.locator(
'[data-test-id="input-manual-address"] textarea',
);
await $manualSecret.waitFor({ state: "visible", timeout: 1000 });
await $manualAddress.waitFor({ state: "visible", timeout: 1000 });
expect(await $manualSecret.inputValue()).toBe(privateKey);
expect(await $manualAddress.inputValue()).toBe(address);
}

// Generate paper wallet
{
await $manualSecret.fill("test-secret");
await $manualAddress.fill("test-address");

const $manualGeneratePaperWalletButton = page.locator(
'[data-test-id="button-submit-manual-wallet"]',
);
await $manualGeneratePaperWalletButton.click();

const $canvas = page.locator('[data-test-el="paper-wallet-canvas"]');
const $firstCanvas = $canvas.first();
const $secondCanvas = $canvas.nth(1);

await $firstCanvas.waitFor({ state: "visible", timeout: 1000 });
await expect($canvas.first()).toHaveScreenshot(
"first-test-secret-address.png",
);

await $secondCanvas.waitFor({ state: "visible", timeout: 1000 });
await expect($canvas.nth(1)).toHaveScreenshot(
"second-test-secret-address.png",
);
}

// todo add download test
// const download = await page.waitForEvent("download", { timeout: 1000 });
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"preview": "vite preview",
"test:unit": "vitest",
"test:e2e": "playwright test --reporter=list",
"test:e2e:update-snapshots": "playwright test --update-snapshots",
"test:e2e:ui": " playwright test --ui",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
:min="10"
/>
<NInputNumber
data-test-id="input-count-tokens"
v-model:value="count"
:min="1"
size="small"
Expand Down
16 changes: 13 additions & 3 deletions src/entities/CryptoWallets/ui/KeyAddressItem/KeyAddressItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@
</script>

<template>
<n-list-item>
<n-list-item data-test-el="key-address-item">
<n-timeline>
<n-timeline-item title="Private Key">
<n-space
vertical
:size="12"
>
<div style="word-break: break-all">{{ keyFormatted }}</div>
<div
style="word-break: break-all"
data-test-el="private-key"
>
{{ keyFormatted }}
</div>
</n-space>
</n-timeline-item>
<n-timeline-item
Expand All @@ -26,7 +31,12 @@
vertical
:size="12"
>
<div style="word-break: break-all">{{ address }}</div>
<div
style="word-break: break-all"
data-test-el="address"
>
{{ address }}
</div>
</n-space>
</n-timeline-item>
</n-timeline>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
}"
@keydown.enter.space.prevent="handleKeydown"
maxlength="154"
data-test-id="input-manual-secret"
/>
</NFormItem>
<NFormItem
Expand All @@ -129,12 +130,14 @@
maxRows: 3,
}"
maxlength="154"
data-test-id="input-manual-address"
/>
</NFormItem>
<NSpace>
<NButton
type="primary"
attr-type="submit"
data-test-id="button-submit-manual-wallet"
>
Get Paper Wallets
</NButton>
Expand Down
1 change: 1 addition & 0 deletions src/entities/PageHeader/ui/PageHeader/PageHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
style="max-width: 250px; text-align: left; margin: 0 auto; width: 100%"
>
<NMenu
data-test-id="page-header-menu"
:options="menuOptions"
v-model:value="selectedKey"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
'paper-wallet-canvas--print-mode': view === 'PRINT',
}"
ref="targetElement"
data-test-el="paper-wallet-canvas"
>
<template
v-for="item in items"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
</script>

<template>
<NButton @click="handleSaveToClipboard">
<NButton
@click="handleSaveToClipboard"
data-test-id="button-copy-wallet-to-clipboard"
>
<template #icon>
<NIcon>
<ClipboardTextRtl24Regular v-show="status === 'initial'" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
</script>

<template>
<NButton @click="handleGeneratePaperWallets">
<NButton
@click="handleGeneratePaperWallets"
data-test-el="button-generate-paper-wallet"
>
<template #icon>
<NIcon>
<Print24Regular />
Expand Down
7 changes: 6 additions & 1 deletion src/features/ShowQrCodes/ui/ShowQrCodes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
</script>

<template>
<NButton @click="showModal = true">
<NButton
@click="showModal = true"
data-test-el="button-show-qr-codes"
>
<template #icon>
<NIcon>
<QrCode20Regular />
Expand All @@ -53,6 +56,7 @@
<NThing
title="Secret"
:description="secret"
data-test-id="dialog-qr-code-secret"
>
<QRCode
:text="secret"
Expand All @@ -62,6 +66,7 @@
<NThing
title="Address"
:description="address"
data-test-id="dialog-qr-code-address"
>
<QRCode
:text="address"
Expand Down