diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index f73bdcdd0..bc89b6cf0 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -70,19 +70,25 @@ jobs: echo "πŸš€ TON Connect Bridge service is now running and accessible at http://localhost:8081/bridge" # uses: ton-connect/bridge/actions/local@master - - - name: Run extension e2e specs + + - name: Run web e2e specs run: xvfb-run pnpm --filter demo-wallet e2e env: WALLET_MNEMONIC: ${{ secrets.WALLET_MNEMONIC }} - E2E_WALLET_SOURCE_EXTENSION: "${{ github.workspace }}/apps/demo-wallet/dist-extension" - E2E_JS_BRIDGE: true + VITE_BRIDGE_URL: 'http://localhost:8081/bridge' + ALLURE_BASE_URL: ${{ secrets.ALLURE_BASE_URL }} + ALLURE_API_TOKEN: ${{ secrets.ALLURE_API_TOKEN }} + ALLURE_PROJECT_ID: ${{ secrets.ALLURE_PROJECT_ID }} - - name: Run web e2e specs + - name: Run extension e2e specs run: xvfb-run pnpm --filter demo-wallet e2e env: WALLET_MNEMONIC: ${{ secrets.WALLET_MNEMONIC }} - VITE_BRIDGE_URL: 'http://localhost:8081/bridge' + E2E_WALLET_SOURCE_EXTENSION: "${{ github.workspace }}/apps/demo-wallet/dist-extension" + E2E_JS_BRIDGE: true + ALLURE_BASE_URL: ${{ secrets.ALLURE_BASE_URL }} + ALLURE_API_TOKEN: ${{ secrets.ALLURE_API_TOKEN }} + ALLURE_PROJECT_ID: ${{ secrets.ALLURE_PROJECT_ID }} - name: Send report if: always() @@ -97,4 +103,4 @@ jobs: env: ALLURE_BASE_URL: ${{ secrets.ALLURE_BASE_URL }} ALLURE_API_TOKEN: ${{ secrets.ALLURE_API_TOKEN }} - ALLURE_PROJECT_ID: ${{ secrets.ALLURE_PROJECT_ID }} \ No newline at end of file + ALLURE_PROJECT_ID: ${{ secrets.ALLURE_PROJECT_ID }} diff --git a/apps/demo-wallet/e2e.config.ts b/apps/demo-wallet/e2e.config.ts index 7d6c717ac..875e277c4 100644 --- a/apps/demo-wallet/e2e.config.ts +++ b/apps/demo-wallet/e2e.config.ts @@ -1,6 +1,9 @@ -import 'dotenv/config'; +import { config } from 'dotenv'; import { defineConfig, devices } from '@playwright/test'; +// Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния ΠΈΠ· .env Ρ„Π°ΠΉΠ»Π° +config(); + export default defineConfig({ testDir: './e2e', timeout: 120_000, @@ -12,6 +15,18 @@ export default defineConfig({ screenshot: 'on', trace: 'on', permissions: ['clipboard-read', 'clipboard-write'], + launchOptions: { + args: [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-dev-shm-usage', + '--no-first-run', + '--disable-infobars', + '--disable-blink-features=AutomationControlled', + '--use-fake-ui-for-media-stream', + '--disable-permissions-api', + ], + }, }, projects: process.env.E2E_WALLET_SOURCE_EXTENSION ? [ diff --git a/apps/demo-wallet/e2e/connect.spec.ts b/apps/demo-wallet/e2e/connect.spec.ts index 6c5e498f1..adc81b99f 100644 --- a/apps/demo-wallet/e2e/connect.spec.ts +++ b/apps/demo-wallet/e2e/connect.spec.ts @@ -1,83 +1,51 @@ -//import * as allure from 'allure-js-commons'; - -import { expect } from '@playwright/test'; -import { allure } from 'allure-playwright'; +import { config } from 'dotenv'; import type { TestInfo } from '@playwright/test'; +import { expect } from '@playwright/test'; +import { allureId, owner } from 'allure-js-commons'; import { testWithDemoWalletFixture } from './demo-wallet'; -import { AllureApiClient, createAllureConfig, getTestCaseData, extractAllureId } from './utils'; import type { TestFixture } from './qa'; +import { AllureApiClient, createAllureConfig, getTestCaseData, extractAllureId } from './utils'; +config(); + +// const feature = { +// jsBridge: Boolean(process.env.E2E_JS_BRIDGE), +// }; const test = testWithDemoWalletFixture({ appUrl: process.env.DAPP_URL ?? 'https://allure-test-runner.vercel.app/e2e', }); -//const { expect } = test; - -// const test = testWith( -// demoWalletFixture({ -// extensionPath: 'dist-extension', -// mnemonic: -// process.env.WALLET_MNEMONIC || -// 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about', -// appUrl: process.env.DAPP_URL || 'https://allure-test-runner.vercel.app/e2e ' -// }, 0), -// ); let allureClient: AllureApiClient; test.beforeAll(async () => { - try { - const config = createAllureConfig(); - allureClient = new AllureApiClient(config); - } catch (error) { - // eslint-disable-next-line no-console - console.error('Error creating allure client:', error); - throw error; - } + const config = createAllureConfig(); + allureClient = new AllureApiClient(config); }); async function runConnectTest( { wallet, app, widget }: Pick, testInfo: TestInfo, ) { - const allureId = extractAllureId(testInfo.title); - if (allureId) { - await allure.allureId(allureId); - await allure.owner('e.kurilenko'); + const testAllureId = extractAllureId(testInfo.title); + if (testAllureId) { + await allureId(testAllureId); + await owner('e.kurilenko'); } - let precondition: string = ''; let expectedResult: string = ''; - if (allureId && allureClient) { - try { - const testCaseData = await getTestCaseData(allureClient, allureId); - precondition = testCaseData.precondition; - expectedResult = testCaseData.expectedResult; - } catch (error) { - // eslint-disable-next-line no-console - console.error('Error getting test case data:', error); - } - } else { - // eslint-disable-next-line no-console - console.warn('AllureId not found in test title or client not available'); + if (testAllureId && allureClient) { + const testCaseData = await getTestCaseData(allureClient, testAllureId); + precondition = testCaseData.precondition; + expectedResult = testCaseData.expectedResult; } await app.getByTestId('connectPrecondition').fill(precondition || ''); await app.getByTestId('connectExpectedResult').fill(expectedResult); await expect(app.getByTestId('connect-button')).toHaveText('Connect Wallet'); - - await app.getByTestId('connect-button').click(); - - await widget.connectUrlButton.waitFor({ state: 'visible' }); - await widget.connectUrlButton.click(); - - await wallet.connectBy(await widget.connectUrl()); - - //await wallet.connect(true, await handle.jsonValue()); - - //await wallet.connect(); - - await expect(app.getByTestId('connectValidation')).toHaveText('Validation Passed'); + await wallet.connectBy(await widget.connectUrl(await app.getByTestId('connect-button'))); + await app.getByTestId('connectValidation').waitFor({ state: 'visible' }); + await expect(app.getByTestId('connectValidation')).toHaveText('Validation Passed', { timeout: 1 }); } test('Connect @allureId(1933)', async ({ wallet, app, widget }) => { diff --git a/apps/demo-wallet/e2e/demo-wallet/DemoWallet.ts b/apps/demo-wallet/e2e/demo-wallet/DemoWallet.ts index cff9fcd90..f1342d7f3 100644 --- a/apps/demo-wallet/e2e/demo-wallet/DemoWallet.ts +++ b/apps/demo-wallet/e2e/demo-wallet/DemoWallet.ts @@ -33,6 +33,7 @@ export class DemoWallet extends WalletApp { await app.getByTestId('auto-lock').click(); await app.getByTestId('hold-to-sign').waitFor({ state: 'attached' }); await app.getByTestId('hold-to-sign').click(); + await app.getByTestId('network-select').selectOption('mainnet'); await this.close(); } @@ -65,6 +66,13 @@ export class DemoWallet extends WalletApp { await this.close(); } + async sendTransaction(isPositiveCase: boolean, confirm: boolean): Promise { + await this.open(); + if (isPositiveCase) { + await this.accept(confirm); + } + } + async accept(confirm: boolean = true): Promise { const app = await this.open(); const modal = app.getByTestId('request').filter({ hasText: 'Transaction Request' }); diff --git a/apps/demo-wallet/e2e/demo-wallet/demoWalletFixture.ts b/apps/demo-wallet/e2e/demo-wallet/demoWalletFixture.ts index 0d63ba206..8c1a8d347 100644 --- a/apps/demo-wallet/e2e/demo-wallet/demoWalletFixture.ts +++ b/apps/demo-wallet/e2e/demo-wallet/demoWalletFixture.ts @@ -28,6 +28,7 @@ export function demoWalletFixture(config: ConfigFixture, slowMo = 0) { const walletSource = config.walletSource ?? detectWalletSource(); const isExtension = isExtensionWalletSource(walletSource); const mnemonic = config.mnemonic ?? process.env.WALLET_MNEMONIC; + return test.extend({ context: async ({ context: _ }, use) => { const extensionPath = isExtension ? walletSource : ''; diff --git a/apps/demo-wallet/e2e/qa/TonConnectWidget.ts b/apps/demo-wallet/e2e/qa/TonConnectWidget.ts index 3108601ec..35eef9b92 100644 --- a/apps/demo-wallet/e2e/qa/TonConnectWidget.ts +++ b/apps/demo-wallet/e2e/qa/TonConnectWidget.ts @@ -1,4 +1,4 @@ -import { type Page } from '@playwright/test'; +import { type Page, type Locator } from '@playwright/test'; interface TonConnectSelector { title: string; @@ -57,15 +57,27 @@ export class TonConnectWidget { return this.page.getByRole('button', { name }).click(); } + async copyConnectUrl() { + await this.connectUrlButton.waitFor({ state: 'visible' }); + await this.connectUrlButton.click(); + const handle = await this.page.evaluateHandle(() => navigator.clipboard.readText()); + return await handle.jsonValue(); + } + async connectWallet(name: string) { await this.connect(); await this.clickButton(name); await this.clickButton('Browser Extension'); } - async connect() { - await this.connectButton.waitFor({ state: 'visible' }); - await this.connectButton.click(); + async connect(buttonToClick?: Locator) { + if (buttonToClick) { + await buttonToClick.waitFor({ state: 'visible' }); + await buttonToClick.click(); + } else { + await this.connectButton.waitFor({ state: 'visible' }); + await this.connectButton.click(); + } await this.title.waitFor({ state: 'visible' }); } @@ -75,7 +87,14 @@ export class TonConnectWidget { await this.connectDropdown.locator('li:nth-child(2) > button').click(); } - async connectUrl() { + async connectUrl(buttonToClick?: Locator) { + await this.connect(buttonToClick); + await this.connectUrlButton.waitFor({ state: 'visible' }); + await this.connectUrlButton.click(); + const handle = await this.page.evaluateHandle(() => navigator.clipboard.readText()); + return await handle.jsonValue(); + } + async connectUrlTest() { await this.connect(); await this.connectUrlButton.waitFor({ state: 'visible' }); await this.connectUrlButton.click(); diff --git a/apps/demo-wallet/e2e/qa/index.ts b/apps/demo-wallet/e2e/qa/index.ts index b0a217b1f..246792f8a 100644 --- a/apps/demo-wallet/e2e/qa/index.ts +++ b/apps/demo-wallet/e2e/qa/index.ts @@ -12,12 +12,12 @@ export interface ConfigFixture { mnemonic?: string; } -import { WalletApp } from './WalletApp'; import { TonConnectWidget } from './TonConnectWidget'; +import { DemoWallet } from '../demo-wallet'; export type TestFixture = { context: BrowserContext; - wallet: WalletApp; + wallet: DemoWallet; widget: TonConnectWidget; app: Page; }; diff --git a/apps/demo-wallet/e2e/qa/test.ts b/apps/demo-wallet/e2e/qa/test.ts index d4614c710..a7cdc9ba2 100644 --- a/apps/demo-wallet/e2e/qa/test.ts +++ b/apps/demo-wallet/e2e/qa/test.ts @@ -2,7 +2,17 @@ import { chromium, type Fixtures, type TestType } from '@playwright/test'; import { mergeTests, test as base } from '@playwright/test'; export function launchPersistentContext(extensionPath: string, slowMo = 0) { - const args = []; + const args = [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-dev-shm-usage', + '--no-first-run', + '--disable-infobars', + '--disable-blink-features=AutomationControlled', + '--use-fake-ui-for-media-stream', + '--disable-permissions-api', + ]; + if (extensionPath != '') { args.push(`--disable-extensions-except=${extensionPath}`); args.push(`--load-extension=${extensionPath}`); @@ -10,7 +20,7 @@ export function launchPersistentContext(extensionPath: string, slowMo = 0) { if (process.env.CI) { args.push('--headless=new'); } - slowMo = process.env.CI ? 0 : (parseInt(process.env.E2E_SLOW_MO) ?? slowMo); + slowMo = process.env.CI ? 0 : (parseInt(process.env.E2E_SLOW_MO || '0') ?? slowMo); return chromium.launchPersistentContext('', { args, headless: false, diff --git a/apps/demo-wallet/e2e/sendTransaction.spec.ts b/apps/demo-wallet/e2e/sendTransaction.spec.ts deleted file mode 100644 index 487c54ac3..000000000 --- a/apps/demo-wallet/e2e/sendTransaction.spec.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { expect } from '@playwright/test'; -import { allure } from 'allure-playwright'; -import type { TestInfo } from '@playwright/test'; - -import { AllureApiClient, createAllureConfig, getTestCaseData, extractAllureId } from './utils'; -import { testWithDemoWalletFixture } from './demo-wallet'; -import type { TestFixture } from './qa'; - -const test = testWithDemoWalletFixture({ - appUrl: process.env.DAPP_URL ?? 'https://allure-test-runner.vercel.app/e2e', -}); -// Global variable for storing the Allure client -let allureClient: AllureApiClient; - -// Function for extracting allureId from the test title - -// universal function for executing SendTransaction test -async function runSendTransactionTest( - { wallet, app, widget }: Pick, - testInfo: TestInfo, -) { - const allureId = extractAllureId(testInfo.title); - - if (allureId) { - await allure.allureId(allureId); - await allure.owner('e.kurilenko'); - } - - let precondition: string = ''; - let expectedResult: string = ''; - let isPositiveCase: boolean = true; - - if (allureId && allureClient) { - try { - const testCaseData = await getTestCaseData(allureClient, allureId); - precondition = testCaseData.precondition; - expectedResult = testCaseData.expectedResult; - isPositiveCase = testCaseData.isPositiveCase; - } catch (error) { - // eslint-disable-next-line no-console - console.error('Error getting test case data:', error); - } - } else { - // eslint-disable-next-line no-console - console.warn('AllureId not found in test title or client not available'); - } - - await expect(widget.connectButtonText).toHaveText('Connect Wallet'); - await wallet.connectBy(await widget.connectUrl()); - await expect(widget.connectButtonText).not.toHaveText('Connect Wallet'); - await app.getByTestId('sendTxPrecondition').fill(precondition); - await app.getByTestId('sendTxExpectedResult').fill(expectedResult); - await app.getByTestId('send-transaction-button').click(); - - await wallet.accept(isPositiveCase); - - await expect(app.getByTestId('sendTransactionValidation')).toHaveText('Validation Passed'); -} - -test.beforeAll(async () => { - try { - const config = createAllureConfig(); - allureClient = new AllureApiClient(config); - } catch (error) { - // eslint-disable-next-line no-console - console.error('Error creating allure client:', error); - throw error; - } -}); - -// SendTransaction validation tests -test('[address] Error if absent @allureId(1847)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[address] Error if in HEX format @allureId(1870)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[address] Error if invalid value @allureId(1856)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[address] Success if in bounceable format @allureId(1852)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[address] Success if in non-bounceable format @allureId(1853)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[amount] Error if absent @allureId(1873)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[amount] Error if as a number @allureId(1857)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[amount] Error if insufficient balance @allureId(1871)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test("[amount] Success if '0' @allureId(1980)", async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[amount] Success if as a string @allureId(1849)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test("[from] Error if address doesn't match the user's wallet address @allureId(1877)", async ({ - wallet, - app, - widget, -}) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[from] Error if invalid value @allureId(1848)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[from] Success if in bounceable format @allureId(1878)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[from] Success if in HEX format @allureId(1855)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[from] Success if in non-bounceable format @allureId(1862)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[messages] Error if array is empty @allureId(1864)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[messages] Error if contains invalid message @allureId(1869)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[messages] Success if contains maximum messages @allureId(1959)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test("[network] Error if '-3' (testnet) @allureId(1876)", async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[network] Error if as a number @allureId(1860)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test("[network] Success if '-239' (mainnet) @allureId(1875)", async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[payload] Error if invalid value @allureId(1872)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[payload] Success if absent @allureId(1854)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[payload] Success if valid value @allureId(1879)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[stateInit] Error if invalid value @allureId(1874)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[stateInit] Success if absent @allureId(1859)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[stateInit] Success if valid value @allureId(1850)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[validUntil] Success if absent @allureId(1866)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[validUntil] Error if as a string @allureId(1865)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[validUntil] Error if expired @allureId(1861)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[validUntil] Error if has expired during confirmation @allureId(1863)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[validUntil] Error if NaN @allureId(1867)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[validUntil] Error if NULL @allureId(1868)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[validUntil] Success if less then in 5 minutes @allureId(1851)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('[validUntil] Success if more then in 5 minutes @allureId(1858)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -// Merkle proof/update tests -test('Send merkle proof @allureId(1916)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -test('Send merkle update @allureId(1917)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); - -// Jetton minting tests -test('Minting Jetton with Deployed Contract @allureId(1899)', async ({ wallet, app, widget }) => { - await runSendTransactionTest({ wallet, app, widget }, test.info()); -}); diff --git a/apps/demo-wallet/e2e/signData.spec.ts b/apps/demo-wallet/e2e/signData.spec.ts index 36854d17d..3016c0957 100644 --- a/apps/demo-wallet/e2e/signData.spec.ts +++ b/apps/demo-wallet/e2e/signData.spec.ts @@ -1,4 +1,6 @@ -import { allure } from 'allure-playwright'; +import { config } from 'dotenv'; +import { allureId, owner } from 'allure-js-commons'; +config(); import { expect } from '@playwright/test'; import type { TestInfo } from '@playwright/test'; @@ -27,21 +29,21 @@ async function runSignDataTest( { wallet, app, widget }: Pick, testInfo: TestInfo, ) { - const allureId = extractAllureId(testInfo.title); - if (allureId) { - await allure.allureId(allureId); - await allure.owner('e.kurilenko'); + const testAllureId = extractAllureId(testInfo.title); + if (testAllureId) { + await allureId(testAllureId); + await owner('e.kurilenko'); } let precondition: string = ''; let expectedResult: string = ''; - let isPositiveCase: boolean = true; + // let isPositiveCase: boolean = true; - if (allureId && allureClient) { + if (testAllureId && allureClient) { try { - const testCaseData = await getTestCaseData(allureClient, allureId); + const testCaseData = await getTestCaseData(allureClient, testAllureId); precondition = testCaseData.precondition; expectedResult = testCaseData.expectedResult; - isPositiveCase = testCaseData.isPositiveCase; + //isPositiveCase = testCaseData.isPositiveCase; will use it for negative cases later } catch (error) { // eslint-disable-next-line no-console console.error('Error getting test case data:', error); @@ -57,7 +59,7 @@ async function runSignDataTest( await app.getByTestId('signDataExpectedResult').fill(expectedResult); await app.getByTestId('sign-data-button').click(); - await wallet.signData(isPositiveCase); + await wallet.signData(true); await expect(app.getByTestId('signDataValidation')).toHaveText('Validation Passed'); } diff --git a/apps/demo-wallet/e2e/signTransaction/sendTransaction1.spec.ts b/apps/demo-wallet/e2e/signTransaction/sendTransaction1.spec.ts new file mode 100644 index 000000000..4bae6778d --- /dev/null +++ b/apps/demo-wallet/e2e/signTransaction/sendTransaction1.spec.ts @@ -0,0 +1,107 @@ +import { config } from 'dotenv'; +import { expect } from '@playwright/test'; +import { allureId, owner } from 'allure-js-commons'; +import type { TestInfo } from '@playwright/test'; + +import { AllureApiClient, createAllureConfig, getTestCaseData, extractAllureId } from '../utils'; +import { testWithDemoWalletFixture } from '../demo-wallet'; +import type { TestFixture } from '../qa'; +config(); + +const test = testWithDemoWalletFixture({ + appUrl: process.env.DAPP_URL ?? 'https://allure-test-runner.vercel.app/e2e', +}); +// Global variable for storing the Allure client +let allureClient: AllureApiClient; + +test.beforeAll(async () => { + try { + const config = createAllureConfig(); + allureClient = new AllureApiClient(config); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error creating allure client:', error); + throw error; + } +}); + +async function runSendTransactionTest( + { wallet, app, widget }: Pick, + testInfo: TestInfo, +) { + const testAllureId = extractAllureId(testInfo.title); + + if (testAllureId) { + await allureId(testAllureId); + await owner('e.kurilenko'); + } + + let precondition: string = ''; + let expectedResult: string = ''; + let isPositiveCase: boolean = true; + + if (testAllureId && allureClient) { + try { + const testCaseData = await getTestCaseData(allureClient, testAllureId); + precondition = testCaseData.precondition; + expectedResult = testCaseData.expectedResult; + isPositiveCase = testCaseData.isPositiveCase; + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error getting test case data:', error); + } + } else { + // eslint-disable-next-line no-console + console.warn('AllureId not found in test title or client not available'); + } + + await expect(widget.connectButtonText).toHaveText('Connect Wallet'); + await wallet.connectBy(await widget.connectUrl()); + await expect(widget.connectButtonText).not.toHaveText('Connect Wallet'); + await app.getByTestId('sendTxPrecondition').fill(precondition); + await app.getByTestId('sendTxExpectedResult').fill(expectedResult); + await app.getByTestId('send-transaction-button').click(); + + await wallet.sendTransaction(isPositiveCase, true); + + await expect(app.getByTestId('sendTransactionValidation')).toHaveText('Validation Passed'); +} + +// SendTransaction validation tests +test('[address] Error if absent @allureId(1847)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[address] Error if in HEX format @allureId(1870)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[address] Error if invalid value @allureId(1856)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[address] Success if in bounceable format @allureId(1852)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[address] Success if in non-bounceable format @allureId(1853)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[amount] Error if absent @allureId(1873)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +// Merkle proof/update tests +test('Send merkle proof @allureId(1916)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('Send merkle update @allureId(1917)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +// Jetton minting tests +test('Minting Jetton with Deployed Contract @allureId(1899)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); diff --git a/apps/demo-wallet/e2e/signTransaction/sendTransaction2.spec.ts b/apps/demo-wallet/e2e/signTransaction/sendTransaction2.spec.ts new file mode 100644 index 000000000..aca0d035b --- /dev/null +++ b/apps/demo-wallet/e2e/signTransaction/sendTransaction2.spec.ts @@ -0,0 +1,129 @@ +import { config } from 'dotenv'; +import { expect } from '@playwright/test'; +import { allureId, owner } from 'allure-js-commons'; +import type { TestInfo } from '@playwright/test'; + +import { AllureApiClient, createAllureConfig, getTestCaseData, extractAllureId } from '../utils'; +import { testWithDemoWalletFixture } from '../demo-wallet'; +import type { TestFixture } from '../qa'; +config(); + +const test = testWithDemoWalletFixture({ + appUrl: process.env.DAPP_URL ?? 'https://allure-test-runner.vercel.app/e2e', +}); +// Global variable for storing the Allure client +let allureClient: AllureApiClient; + +test.beforeAll(async () => { + try { + const config = createAllureConfig(); + allureClient = new AllureApiClient(config); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error creating allure client:', error); + throw error; + } +}); + +async function runSendTransactionTest( + { wallet, app, widget }: Pick, + testInfo: TestInfo, +) { + const testAllureId = extractAllureId(testInfo.title); + + if (testAllureId) { + await allureId(testAllureId); + await owner('e.kurilenko'); + } + + let precondition: string = ''; + let expectedResult: string = ''; + let isPositiveCase: boolean = true; + + if (testAllureId && allureClient) { + try { + const testCaseData = await getTestCaseData(allureClient, testAllureId); + precondition = testCaseData.precondition; + expectedResult = testCaseData.expectedResult; + isPositiveCase = testCaseData.isPositiveCase; + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error getting test case data:', error); + } + } else { + // eslint-disable-next-line no-console + console.warn('AllureId not found in test title or client not available'); + } + + await expect(widget.connectButtonText).toHaveText('Connect Wallet'); + await wallet.connectBy(await widget.connectUrl()); + await expect(widget.connectButtonText).not.toHaveText('Connect Wallet'); + await app.getByTestId('sendTxPrecondition').fill(precondition); + await app.getByTestId('sendTxExpectedResult').fill(expectedResult); + await app.getByTestId('send-transaction-button').click(); + + await wallet.sendTransaction(isPositiveCase, true); + + await expect(app.getByTestId('sendTransactionValidation')).toHaveText('Validation Passed'); +} + +// SendTransaction validation tests +// test('[address] Error if absent @allureId(1847)', async ({ wallet, app, widget }) => { +// await runSendTransactionTest({ wallet, app, widget }, test.info()); +// }); + +// test('[address] Error if in HEX format @allureId(1870)', async ({ wallet, app, widget }) => { +// await runSendTransactionTest({ wallet, app, widget }, test.info()); +// }); + +// test('[address] Error if invalid value @allureId(1856)', async ({ wallet, app, widget }) => { +// await runSendTransactionTest({ wallet, app, widget }, test.info()); +// }); + +// test('[address] Success if in bounceable format @allureId(1852)', async ({ wallet, app, widget }) => { +// await runSendTransactionTest({ wallet, app, widget }, test.info()); +// }); + +// test('[address] Success if in non-bounceable format @allureId(1853)', async ({ wallet, app, widget }) => { +// await runSendTransactionTest({ wallet, app, widget }, test.info()); +// }); + +// test('[amount] Error if absent @allureId(1873)', async ({ wallet, app, widget }) => { +// await runSendTransactionTest({ wallet, app, widget }, test.info()); +// }); + +test('[amount] Error if as a number @allureId(1857)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[amount] Error if insufficient balance @allureId(1871)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test("[amount] Success if '0' @allureId(1980)", async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[amount] Success if as a string @allureId(1849)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test("[from] Error if address doesn't match the user's wallet address @allureId(1877)", async ({ + wallet, + app, + widget, +}) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[payload] Success if valid value @allureId(1879)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[stateInit] Error if invalid value @allureId(1874)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[stateInit] Success if absent @allureId(1859)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); diff --git a/apps/demo-wallet/e2e/signTransaction/sendTransaction3.spec.ts b/apps/demo-wallet/e2e/signTransaction/sendTransaction3.spec.ts new file mode 100644 index 000000000..c70830bd5 --- /dev/null +++ b/apps/demo-wallet/e2e/signTransaction/sendTransaction3.spec.ts @@ -0,0 +1,100 @@ +import { config } from 'dotenv'; +import { expect } from '@playwright/test'; +import { allureId, owner } from 'allure-js-commons'; +import type { TestInfo } from '@playwright/test'; + +import { AllureApiClient, createAllureConfig, getTestCaseData, extractAllureId } from '../utils'; +import { testWithDemoWalletFixture } from '../demo-wallet'; +import type { TestFixture } from '../qa'; +config(); + +const test = testWithDemoWalletFixture({ + appUrl: process.env.DAPP_URL ?? 'https://allure-test-runner.vercel.app/e2e', +}); +// Global variable for storing the Allure client +let allureClient: AllureApiClient; + +test.beforeAll(async () => { + try { + const config = createAllureConfig(); + allureClient = new AllureApiClient(config); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error creating allure client:', error); + throw error; + } +}); + +async function runSendTransactionTest( + { wallet, app, widget }: Pick, + testInfo: TestInfo, +) { + const testAllureId = extractAllureId(testInfo.title); + + if (testAllureId) { + await allureId(testAllureId); + await owner('e.kurilenko'); + } + + let precondition: string = ''; + let expectedResult: string = ''; + let isPositiveCase: boolean = true; + + if (testAllureId && allureClient) { + try { + const testCaseData = await getTestCaseData(allureClient, testAllureId); + precondition = testCaseData.precondition; + expectedResult = testCaseData.expectedResult; + isPositiveCase = testCaseData.isPositiveCase; + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error getting test case data:', error); + } + } else { + // eslint-disable-next-line no-console + console.warn('AllureId not found in test title or client not available'); + } + + await expect(widget.connectButtonText).toHaveText('Connect Wallet'); + await wallet.connectBy(await widget.connectUrl()); + await expect(widget.connectButtonText).not.toHaveText('Connect Wallet'); + await app.getByTestId('sendTxPrecondition').fill(precondition); + await app.getByTestId('sendTxExpectedResult').fill(expectedResult); + await app.getByTestId('send-transaction-button').click(); + + await wallet.sendTransaction(isPositiveCase, true); + + await expect(app.getByTestId('sendTransactionValidation')).toHaveText('Validation Passed'); +} + +test('[from] Error if invalid value @allureId(1848)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[from] Success if in bounceable format @allureId(1878)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[from] Success if in HEX format @allureId(1855)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[from] Success if in non-bounceable format @allureId(1862)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[messages] Error if array is empty @allureId(1864)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[validUntil] Error if NULL @allureId(1868)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[validUntil] Success if less then in 5 minutes @allureId(1851)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[validUntil] Success if more then in 5 minutes @allureId(1858)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); diff --git a/apps/demo-wallet/e2e/signTransaction/sendTransaction4.spec.ts b/apps/demo-wallet/e2e/signTransaction/sendTransaction4.spec.ts new file mode 100644 index 000000000..5fd246f58 --- /dev/null +++ b/apps/demo-wallet/e2e/signTransaction/sendTransaction4.spec.ts @@ -0,0 +1,96 @@ +import { config } from 'dotenv'; +import { expect } from '@playwright/test'; +import { allureId, owner } from 'allure-js-commons'; +import type { TestInfo } from '@playwright/test'; + +import { AllureApiClient, createAllureConfig, getTestCaseData, extractAllureId } from '../utils'; +import { testWithDemoWalletFixture } from '../demo-wallet'; +import type { TestFixture } from '../qa'; +config(); + +const test = testWithDemoWalletFixture({ + appUrl: process.env.DAPP_URL ?? 'https://allure-test-runner.vercel.app/e2e', +}); +// Global variable for storing the Allure client +let allureClient: AllureApiClient; + +test.beforeAll(async () => { + try { + const config = createAllureConfig(); + allureClient = new AllureApiClient(config); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error creating allure client:', error); + throw error; + } +}); + +async function runSendTransactionTest( + { wallet, app, widget }: Pick, + testInfo: TestInfo, +) { + const testAllureId = extractAllureId(testInfo.title); + + if (testAllureId) { + await allureId(testAllureId); + await owner('e.kurilenko'); + } + + let precondition: string = ''; + let expectedResult: string = ''; + let isPositiveCase: boolean = true; + + if (testAllureId && allureClient) { + try { + const testCaseData = await getTestCaseData(allureClient, testAllureId); + precondition = testCaseData.precondition; + expectedResult = testCaseData.expectedResult; + isPositiveCase = testCaseData.isPositiveCase; + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error getting test case data:', error); + } + } else { + // eslint-disable-next-line no-console + console.warn('AllureId not found in test title or client not available'); + } + + await expect(widget.connectButtonText).toHaveText('Connect Wallet'); + await wallet.connectBy(await widget.connectUrl()); + await expect(widget.connectButtonText).not.toHaveText('Connect Wallet'); + await app.getByTestId('sendTxPrecondition').fill(precondition); + await app.getByTestId('sendTxExpectedResult').fill(expectedResult); + await app.getByTestId('send-transaction-button').click(); + + await wallet.sendTransaction(isPositiveCase, true); + + await expect(app.getByTestId('sendTransactionValidation')).toHaveText('Validation Passed'); +} + +test('[messages] Error if contains invalid message @allureId(1869)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[messages] Success if contains maximum messages @allureId(1959)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test("[network] Error if '-3' (testnet) @allureId(1876)", async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[network] Error if as a number @allureId(1860)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test("[network] Success if '-239' (mainnet) @allureId(1875)", async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[payload] Error if invalid value @allureId(1872)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[payload] Success if absent @allureId(1854)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); diff --git a/apps/demo-wallet/e2e/signTransaction/sendTransaction5.spec.ts b/apps/demo-wallet/e2e/signTransaction/sendTransaction5.spec.ts new file mode 100644 index 000000000..fb6689e65 --- /dev/null +++ b/apps/demo-wallet/e2e/signTransaction/sendTransaction5.spec.ts @@ -0,0 +1,91 @@ +import { config } from 'dotenv'; +import { expect } from '@playwright/test'; +import { allureId, owner } from 'allure-js-commons'; +import type { TestInfo } from '@playwright/test'; + +import { AllureApiClient, createAllureConfig, getTestCaseData, extractAllureId } from '../utils'; +import { testWithDemoWalletFixture } from '../demo-wallet'; +import type { TestFixture } from '../qa'; +config(); + +const test = testWithDemoWalletFixture({ + appUrl: process.env.DAPP_URL ?? 'https://allure-test-runner.vercel.app/e2e', +}); +// Global variable for storing the Allure client +let allureClient: AllureApiClient; + +test.beforeAll(async () => { + try { + const config = createAllureConfig(); + allureClient = new AllureApiClient(config); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error creating allure client:', error); + throw error; + } +}); + +async function runSendTransactionTest( + { wallet, app, widget }: Pick, + testInfo: TestInfo, +) { + const testAllureId = extractAllureId(testInfo.title); + + if (testAllureId) { + await allureId(testAllureId); + await owner('e.kurilenko'); + } + + let precondition: string = ''; + let expectedResult: string = ''; + let isPositiveCase: boolean = true; + + if (testAllureId && allureClient) { + try { + const testCaseData = await getTestCaseData(allureClient, testAllureId); + precondition = testCaseData.precondition; + expectedResult = testCaseData.expectedResult; + isPositiveCase = testCaseData.isPositiveCase; + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error getting test case data:', error); + } + } else { + // eslint-disable-next-line no-console + console.warn('AllureId not found in test title or client not available'); + } + + await expect(widget.connectButtonText).toHaveText('Connect Wallet'); + await wallet.connectBy(await widget.connectUrl()); + await expect(widget.connectButtonText).not.toHaveText('Connect Wallet'); + await app.getByTestId('sendTxPrecondition').fill(precondition); + await app.getByTestId('sendTxExpectedResult').fill(expectedResult); + await app.getByTestId('send-transaction-button').click(); + + await wallet.sendTransaction(isPositiveCase, true); + + await expect(app.getByTestId('sendTransactionValidation')).toHaveText('Validation Passed'); +} +test('[stateInit] Success if valid value @allureId(1850)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[validUntil] Success if absent @allureId(1866)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[validUntil] Error if as a string @allureId(1865)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[validUntil] Error if expired @allureId(1861)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[validUntil] Error if has expired during confirmation @allureId(1863)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); + +test('[validUntil] Error if NaN @allureId(1867)', async ({ wallet, app, widget }) => { + await runSendTransactionTest({ wallet, app, widget }, test.info()); +}); diff --git a/apps/demo-wallet/e2e/smoke.spec.ts b/apps/demo-wallet/e2e/smoke.spec.ts index 020de7c09..a10568a83 100644 --- a/apps/demo-wallet/e2e/smoke.spec.ts +++ b/apps/demo-wallet/e2e/smoke.spec.ts @@ -1,6 +1,10 @@ +import { config } from 'dotenv'; //import * as allure from 'allure-js-commons'; import { allure } from 'allure-playwright'; +// Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния +config(); + import { testWithDemoWalletFixture } from './demo-wallet'; const feature = { diff --git a/apps/demo-wallet/e2e/utils.ts b/apps/demo-wallet/e2e/utils.ts index 65c08a7d8..4346955e3 100644 --- a/apps/demo-wallet/e2e/utils.ts +++ b/apps/demo-wallet/e2e/utils.ts @@ -1,3 +1,7 @@ +import { createComponentLogger } from '../src/utils/logger'; + +const log = createComponentLogger('Allure'); + interface TokenResponse { access_token: string; token_type: string; @@ -12,7 +16,9 @@ interface AllureConfig { } /** - * Gets JWT token for Allure TestOps API + * ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ JWT Ρ‚ΠΎΠΊΠ΅Π½ для Allure TestOps API + * @param config - ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ Allure TestOps + * @returns Promise с JWT Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠΌ */ export async function getAllureToken(config: AllureConfig): Promise { const { baseUrl, apiToken } = config; @@ -41,11 +47,18 @@ export async function getAllureToken(config: AllureConfig): Promise { throw new Error(`Error getting Allure token: ${error instanceof Error ? error.message : 'Unknown error'}`); } } - +export type TestCaseData = { + precondition: string; + expectedResult: string; + isPositiveCase: boolean; +}; /** - * Gets test case information by allureId + * ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ тСст-кСйсС ΠΏΠΎ allureId + * @param config - ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ Allure TestOps + * @param allureId - ID тСст-кСйса Π² Allure + * @returns Promise с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ тСст-кСйса */ -export async function getTestCaseByAllureId(config: AllureConfig, allureId: string): Promise { +export async function getTestCaseByAllureId(config: AllureConfig, allureId: string): Promise { const { baseUrl } = config; const token = await getAllureToken(config); @@ -70,14 +83,13 @@ export async function getTestCaseByAllureId(config: AllureConfig, allureId: stri } /** - * Creates Allure TestOps configuration from environment variables + * Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ Allure TestOps ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… окруТСния + * @returns ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ Allure TestOps */ export function createAllureConfig(): AllureConfig { const baseUrl = process.env.ALLURE_BASE_URL || 'https://tontech.testops.cloud'; const apiToken = process.env.ALLURE_API_TOKEN; const projectId = parseInt(process.env.ALLURE_PROJECT_ID || '100'); - // eslint-disable-next-line no-console - console.log(process.env); if (!apiToken) { throw new Error('ALLURE_API_TOKEN environment variable is required'); } @@ -90,7 +102,7 @@ export function createAllureConfig(): AllureConfig { } /** - * Utility for working with Allure TestOps API + * Π£Ρ‚ΠΈΠ»ΠΈΡ‚Π° для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Allure TestOps API */ export class AllureApiClient { private config: AllureConfig; @@ -102,7 +114,7 @@ export class AllureApiClient { } /** - * Gets valid token (with caching) + * ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΎΠΊΠ΅Π½ (с ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ) */ private async getValidToken(): Promise { const now = Date.now(); @@ -117,9 +129,9 @@ export class AllureApiClient { } /** - * Makes authorized request to Allure API + * ВыполняСт Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ запрос ΠΊ Allure API */ - private async makeRequest(endpoint: string, options: Record = {}): Promise { + private async makeRequest(endpoint: string, options: { headers?: Record } = {}): Promise { const token = await this.getValidToken(); const response = await fetch(`${this.config.baseUrl}${endpoint}`, { @@ -140,7 +152,7 @@ export class AllureApiClient { } /** - * Gets test case information by allureId + * ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ тСст-кСйсС ΠΏΠΎ allureId */ async getTestCase(allureId: string): Promise { const response = await this.makeRequest(`/api/rs/testcase/allureId/${allureId}`); @@ -148,7 +160,7 @@ export class AllureApiClient { } /** - * Gets project information + * ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ */ async getProject(): Promise { const response = await this.makeRequest(`/api/rs/project/${this.config.projectId}`); @@ -156,7 +168,7 @@ export class AllureApiClient { } /** - * Gets test plans list + * ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ список тСст-ΠΏΠ»Π°Π½ΠΎΠ² */ async getTestPlans(): Promise { const response = await this.makeRequest(`/api/rs/project/${this.config.projectId}/testplan`); @@ -164,7 +176,9 @@ export class AllureApiClient { } /** - * Gets test case information by ID + * ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ тСст-кСйсС ΠΏΠΎ ID + * @param id - ID тСст-кСйса + * @returns Promise с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ тСст-кСйса */ async getTestCaseById(id: string): Promise { const response = await this.makeRequest(`/api/testcase/${id}`); @@ -173,7 +187,9 @@ export class AllureApiClient { } /** - * Extracts allureId from test title + * Π˜Π·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ allureId ΠΈΠ· названия тСста + * @param testTitle - Π½Π°Π·Π²Π°Π½ΠΈΠ΅ тСста + * @returns allureId ΠΈΠ»ΠΈ null Ссли Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ */ export function extractAllureId(testTitle: string): string | null { const match = testTitle.match(/@allureId\((\d+)\)/); @@ -181,7 +197,10 @@ export function extractAllureId(testTitle: string): string | null { } /** - * Gets test case data and extracts precondition and expectedResult + * ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ тСст-кСйса ΠΈ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ precondition ΠΈ expectedResult + * @param allureClient - ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Allure API + * @param allureId - ID тСст-кСйса + * @returns Promise с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ содСрТащим preconditions ΠΈ expectedResult */ export async function getTestCaseData( allureClient: AllureApiClient, @@ -193,15 +212,20 @@ export async function getTestCaseData( }> { try { const testCaseData = await allureClient.getTestCaseById(allureId); + if (typeof testCaseData !== 'object' || testCaseData === null || !('name' in testCaseData)) { + throw new Error('Test case data is not an object'); + } const isPositiveCase = !String(testCaseData.name).toLowerCase().includes('error'); - return { isPositiveCase, ...testCaseData, + } as unknown as { + precondition: string; + expectedResult: string; + isPositiveCase: boolean; }; } catch (error) { - // eslint-disable-next-line no-console - console.error('Error getting test case data:', error); + log.error('Error getting test case data:', error); throw error; } } diff --git a/apps/demo-wallet/src/components/SettingsDropdown.tsx b/apps/demo-wallet/src/components/SettingsDropdown.tsx index d8f2f19bc..8c4049635 100644 --- a/apps/demo-wallet/src/components/SettingsDropdown.tsx +++ b/apps/demo-wallet/src/components/SettingsDropdown.tsx @@ -298,6 +298,7 @@ export const SettingsDropdown: React.FC = () => {