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

Add playwright tests to sample vite app #1549

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
16 changes: 15 additions & 1 deletion .github/workflows/test-apps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,18 @@ jobs:
# Return to the original directory using absolute path
cd "../"
fi
done
done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently we are duplicating the execution for the apps because they are included in workspaces in package.json. I created this ticket because of that #1500.

I would place this snippet either in a separate yml or (maybe) just get rid of the rest and use this file just for this test so you can also complete the other ticket. Otherwise this new part will be moved eventually.

- name: E2E Test for apps
run: |
# Absolute path to the 'sdk-vite-integration' directory
sdk_vite_integration_directory="$(pwd)/apps/sdk-vite-integration"

# LOG
echo "Running yarn in $sdk_vite_integration_directory"

# Navigate to the directory using absolute path
cd "$sdk_vite_integration_directory"

# Test
yarn test:e2e
3 changes: 3 additions & 0 deletions apps/sdk-vite-integration/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ dist-ssr
*.njsproj
*.sln
*.sw?

# playwright
test-results/
48 changes: 48 additions & 0 deletions apps/sdk-vite-integration/e2e/hash.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { test, expect } from '@playwright/test';
import {
Blake2b256,
Keccak256,
Sha256,
Txt
} from '@vechain/sdk-core/dist/index.mjs';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: I would try to use the normal import. Probably you are doing this because of the issue you described during these days, but I would double-check if you can somehow specify something in the playwright config to load this properly since it should not be required (basically you are saying something like "playwright, load ESM files").


test('Hash example', async ({ page }) => {
await page.goto("/");

const hashLink = page.getByTestId('hash-link');

// Expect link to be visible
await expect(hashLink).toBeVisible();

// Click on link
await hashLink.click();

// Enter content to hash
const content = "SDK is awesome!";
const hashInput = page.getByTestId('contentToHash');
await hashInput.clear();
await hashInput.fill(content);

// Expect hash component to be visible with expected text
const blake2bHash = page.getByTestId('blake2b256HashLabel');
const keccak256Hash = page.getByTestId('keccak256HashLabel');
const sha256Hash = page.getByTestId('sha256HashLabel');
await expect(blake2bHash).toBeVisible();
await expect(keccak256Hash).toBeVisible();
await expect(sha256Hash).toBeVisible();

// Assert hash value for blake2b256
const expectedBlake2b256Hash = Blake2b256.of(Txt.of(content).bytes)
await expect(blake2bHash).toContainText('Blake2b256');
await expect(blake2bHash).toContainText(expectedBlake2b256Hash.toString());

// Assert hash value for keccak256
const expectedKeccak256Hash = Keccak256.of(Txt.of(content).bytes)
await expect(keccak256Hash).toContainText('Keccak256');
await expect(keccak256Hash).toContainText(expectedKeccak256Hash.toString());

// Assert hash value for sha256
const expectedSha256Hash = Sha256.of(Txt.of(content).bytes)
await expect(sha256Hash).toContainText('Sha256');
await expect(sha256Hash).toContainText(expectedSha256Hash.toString());
});
24 changes: 24 additions & 0 deletions apps/sdk-vite-integration/e2e/lastblock.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { test, expect } from '@playwright/test';

test('Latest block example', async ({ page }) => {
await page.goto("/");

const latestBlockLink = page.getByTestId('latest-block-link');

// Expect link to be visible
await expect(latestBlockLink).toBeVisible();

// Click on link
await latestBlockLink.click();

// Click get last block button
const getLastBlockButton = page.getByTestId('getlastblock');
await expect(getLastBlockButton).toBeVisible();
await getLastBlockButton.click();

// Assert last block details
const lastBlockDetails = page.getByTestId('last-block-details');
await expect(lastBlockDetails).toBeVisible();
await expect(lastBlockDetails).toContainText('number');
await expect(lastBlockDetails).toContainText('id');
});
29 changes: 29 additions & 0 deletions apps/sdk-vite-integration/e2e/logs.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { test, expect } from '@playwright/test';

test('Transfer logs example', async ({ page }) => {
await page.goto("/");

const logsLink = page.getByTestId('transfers-link');

// Expect link to be visible
await expect(logsLink).toBeVisible();

// Click on link
await logsLink.click();

// Enter details to get transfer logs
const addressInput = page.getByTestId('address');
const fromBlockInput = page.getByTestId('fromblock');
const toBlockInput = page.getByTestId('toblock');

await addressInput.clear();
await addressInput.fill('0xc3bE339D3D20abc1B731B320959A96A08D479583');
await fromBlockInput.clear();
await fromBlockInput.fill('1');
await toBlockInput.clear();
await toBlockInput.fill('19251959');

// expect logs table to be populated
const tableRows = page.locator('css=[data-testid="logs-table"] tr');
await expect(tableRows).toHaveCount(8); // 8 rows in the table, this is a retryable assertion
});
10 changes: 5 additions & 5 deletions apps/sdk-vite-integration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview",
"test": "vitest --config vitest.node.config.js",
"test:jsdom": "vitest --config vitest.jsdom.config.js"
"test": "vitest",
"test:e2e": "playwright test"
},
"dependencies": {
"@vechain/sdk-core": "1.0.0-rc.4",
Expand All @@ -20,19 +20,19 @@
},
"devDependencies": {
"@eslint/js": "^9.13.0",
"@playwright/test": "^1.49.0",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.4",
"@vitest/browser": "^2.1.5",
"@vitest/browser": "^2.1.6",
"eslint": "^9.13.0",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.14",
"globals": "^15.11.0",
"playwright": "^1.48.2",
"typescript": "~5.6.2",
"typescript-eslint": "^8.10.0",
"vite": "^5.4.11",
"vitest": "^2.1.4",
"vitest": "^2.1.6",
"vitest-browser-react": "^0.0.3"
}
}
44 changes: 44 additions & 0 deletions apps/sdk-vite-integration/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
// Look for test files in the "tests" directory, relative to this configuration file.
testDir: 'e2e',

// Run all tests in parallel.
fullyParallel: true,

// Fail the build on CI if you accidentally left test.only in the source code.
forbidOnly: !!process.env.CI,

// Retry on CI only.
retries: process.env.CI ? 2 : 0,

// Opt out of parallel tests on CI.
workers: process.env.CI ? 1 : undefined,

// Reporter to use, see https://playwright.dev/docs/test-reporters
reporter: 'html',

use: {
// Base URL to use in actions like `await page.goto('/')`.
baseURL: 'http://localhost:5173',

// Collect trace when retrying the failed test.
trace: 'on-first-retry',
},
// Configure projects for major browsers.
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
// Run your local dev server before starting the tests.
webServer: {
command: 'yarn dev',
url: 'http://localhost:5173',
timeout: 120 * 1000,
reuseExistingServer: !process.env.CI,
},
});
6 changes: 3 additions & 3 deletions apps/sdk-vite-integration/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function App() {
<div className="card">
<p>
<b>@vechain/sdk-core</b> integration example:{' '}
<Link
<Link data-testid="hash-link"
className="text-blue-500 hover:underline"
to="/hash" // Change from href to to for React Router
>
Expand All @@ -31,7 +31,7 @@ function App() {
</p>
<p>
<b>@vechain/sdk-network</b> integration example:{' '}
<Link
<Link data-testid="transfers-link"
className="text-blue-500 hover:underline"
to='/transfer-logs'
>
Expand All @@ -40,7 +40,7 @@ function App() {
</p>
<p>
<b>@vechain/sdk-network</b> integration example:{' '}
<Link
<Link data-testid="latest-block-link"
className="text-blue-500 hover:underline"
to='/get-last-block'
>
Expand Down
4 changes: 2 additions & 2 deletions apps/sdk-vite-integration/src/components/GetLastBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ const GetLastBlock = () => {

return (
<div>
<button onClick={fetchLastBlock}>
<button onClick={fetchLastBlock} data-testid="getlastblock">
Get Last Block
</button>
{block && (
<div>
<h3>Last Block Details:</h3>
<pre>{JSON.stringify(block, null, 2)}</pre>
<pre data-testid="last-block-details">{JSON.stringify(block, null, 2)}</pre>
</div>
)}
</div>
Expand Down
88 changes: 67 additions & 21 deletions apps/sdk-vite-integration/src/components/TransferLogs.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useEffect, useState } from "react";
import { Address, FixedPointNumber, Units } from '@vechain/sdk-core';
import {
CompressedBlockDetail,
FilterTransferLogsOptions
} from '@vechain/sdk-network';
import { Link } from 'react-router-dom';
Expand Down Expand Up @@ -31,15 +30,16 @@
'0xc3bE339D3D20abc1B731B320959A96A08D479583'
);

const [fromBlock, setFromBlock] = useState<number>(1);
const [toBlock, setToBlock] = useState<number>(19251959);

// /**
// * Function to get the history for the provided address
// * @param address The address to get the history for
// */
async function getHistoryFor(address: string): Promise<void> {
try {
// Get the latest block
const bestBlock = await thorClient.blocks.getBestBlockCompressed();


// Filter options for the transfer logs
const filterOptions: FilterTransferLogsOptions = {
criteriaSet: [
Expand All @@ -49,8 +49,8 @@
order: 'desc', // Order logs by descending timestamp
range: {
unit: 'block',
from: 0,
to: (bestBlock as CompressedBlockDetail).number
from: fromBlock,
to: toBlock
}
};

Expand All @@ -76,31 +76,77 @@

// Update the history when the address changes
useEffect(() => {
if (Address.isValid(address)) {
if (Address.isValid(address) && fromBlock) {
void getHistoryFor(address);
}
}, [address]);
}, [address, fromBlock, toBlock]);

Check warning on line 82 in apps/sdk-vite-integration/src/components/TransferLogs.tsx

View workflow job for this annotation

GitHub Actions / install-build / Build & Lint

React Hook useEffect has a missing dependency: 'getHistoryFor'. Either include it or remove the dependency array

return (
<main className="isolate bg-white px-6 py-24 sm:py-32 lg:px-8">
<div className="my-20 mx-auto max-w-2xl text-center">
<p className="my-5 text-lg leading-8 text-gray-600">
Insert an address to get the transfer history
Insert an address, fromBlock and ToBlock number to get the transfer logs
</p>
<input
type="text"
name="address"
data-testid="address"
onChange={(e) => {
setAddress(e.target.value);
}}
value={address}
className="block mx-auto w-full sm:max-w-md border-2 border-dark focus:border-purple-500 bg-transparent py-2 px-4 text-lg text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6 outline-none rounded-md"
placeholder="0xc3bE339D3D20abc1B731B320959A96A08D479583"
/>
<div>
<label
htmlFor="address"
className="block text-sm font-medium text-gray-700"
>
Address
</label>
<input
type="text"
name="address"
data-testid="address"
onChange={(e) => {
setAddress(e.target.value);
}}
value={address}
className="block mx-auto w-full sm:max-w-md border-2 border-dark focus:border-purple-500 bg-transparent py-2 px-4 text-lg text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6 outline-none rounded-md"
placeholder="0xc3bE339D3D20abc1B731B320959A96A08D479583"
/>
</div>
<div>
<label
htmlFor="fromblock"
className="block text-sm font-medium text-gray-700"
>
FromBlock
</label>
<input
type="number"
name="fromblock"
data-testid="fromblock"
onChange={(e) => {
setFromBlock(parseInt(e.target.value));
}}
value={fromBlock}
className="block mx-auto w-full sm:max-w-md border-2 border-dark focus:border-purple-500 bg-transparent py-2 px-4 text-lg text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6 outline-none rounded-md"
placeholder="1"
/>
</div>
<div>
<label
htmlFor="Toblock"
className="block text-sm font-medium text-gray-700"
>
ToBlock
</label>
<input
type="number"
name="toblock"
data-testid="toblock"
onChange={(e) => {
setToBlock(parseInt(e.target.value));
}}
value={toBlock}
className="block mx-auto w-full sm:max-w-md border-2 border-dark focus:border-purple-500 bg-transparent py-2 px-4 text-lg text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6 outline-none rounded-md"
placeholder="19251959"
/>
</div>
</div>
<div className="table-container mx-auto max-w-4xl overflow-x-auto text-center justify-center flex flex-col">
<table className="table-auto">
<table className="table-auto" data-testid="logs-table">
<thead>
<tr>
<th className="px-4 py-2">Time</th>
Expand Down
2 changes: 1 addition & 1 deletion apps/sdk-vite-integration/tsconfig.tsbuildinfo
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"root":["./vite.config.ts","./vitest.jsdom.config.ts","./vitest.node.config.ts","./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/components/getlastblock.tsx","./src/components/hash.tsx","./src/components/transferlogs.tsx","./src/const/const.tsx","./src/const/index.tsx","./src/types/index.tsx","./src/types/types.d.tsx","./tests/hash.spec.tsx"],"version":"5.6.3"}
{"root":["./playwright.config.ts","./vite.config.ts","./vitest.workspace.ts","./e2e/hash.spec.ts","./e2e/lastblock.spec.ts","./e2e/logs.spec.ts","./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/components/getlastblock.tsx","./src/components/hash.tsx","./src/components/transferlogs.tsx","./src/const/const.tsx","./src/const/index.tsx","./src/types/index.tsx","./src/types/types.d.tsx","./tests/hash.spec.tsx"],"errors":true,"version":"5.6.3"}
Loading