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

feat: injected button e2e test #276

Merged
merged 9 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
10 changes: 10 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,15 @@ module.exports = {
},
env: {
browser: true,
node: true,
},
overrides: [
{
files: ["*.cjs"],
rules: {
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-unsafe-assignment": "off"
}
}
]
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
};
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

[OneKey DApp Example](https://dapp-example.onekeytest.com/)


# Init monorepo

```bash
yarn
yarn bootstrap
yarn build
```

# Develop monorepo

```bash
# Clean cache
yarn clean && yarn bootstrap
Expand All @@ -30,18 +31,55 @@ yarn gulp-watch
```

# Run dapp example web

```bash
yarn example
```

# Update all versions before publish

```bash
yarn update-version 1.0.1
```

# Publish to npmjs.com

```bash
yarn publish-packages
```


# E2E Test

```
# start dev runtime build
yarn && yarn bootstrap && yarn start

# run e2e test headless
yarn test:e2e

# run e2e test headed
yarn test:e2e:headed

# check e2e reports & screenshots
# packages/e2e/playwright-report
# packages/e2e/test-results




```

sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
packages/providers/inpage-providers-hub/src/connectButtonHack/universal/config.ts

skip connectButton site test

```
skip: { mobile: true, desktop: true },
```

only connectButton site test

```
only: true,
```
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"example": "cd ./packages/example && yarn dev",
"example-build": "cd ./packages/example && yarn --registry 'https://registry.npmjs.org' && yarn build",
"update-version": "lerna version --no-git-tag-version --exact",
"swap-lock-registry": "npx swap-lock-registry --yarn --parallel --url https://registry.yarnpkg.com yarn.lock"
"swap-lock-registry": "npx swap-lock-registry --yarn --parallel --url https://registry.yarnpkg.com yarn.lock",
"test:e2e:headed": "cd ./packages/e2e && yarn test:headed",
"test:e2e": "cd ./packages/e2e && yarn test"
},
"devDependencies": {
"@testing-library/react-hooks": "^7.0.2",
Expand All @@ -32,7 +34,7 @@
"@types/jest": "^27.0.2",
"@types/lodash": "^4.14.178",
"@types/lodash-es": "^4.17.12",
"@types/node": "^16.9.0",
"@types/node": "^20.12.7",
"@types/react": "^17.0.21",
"@types/react-native": "^0.67.6",
"@typescript-eslint/eslint-plugin": "^5.7.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/versionInfo.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

const version = '2.2.2';
const version = '2.2.6';
const versionBuild = '2020-0101-1';

export default {
Expand Down
5 changes: 5 additions & 0 deletions packages/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
test-results/
playwright-report/
reports/
playwright/.cache/
20 changes: 20 additions & 0 deletions packages/e2e/dotEnvInit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import dotenv from 'dotenv';
import path from 'path';
import { fileURLToPath } from 'url';
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved

function setupDotEnv() {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const results = [
dotenv.config({
path: path.resolve(__dirname, '../../.env'),
}),
];
const errorResult = results.find((result) => result.error);

if (errorResult) {
throw errorResult.error;
}
}
setupDotEnv();
45 changes: 45 additions & 0 deletions packages/e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"private": true,
"name": "@onekeyfe/e2e",
"version": "2.2.6",
"keywords": [
"cross-inpage-provider"
],
"author": "[email protected]",
"repository": "https://github.com/OneKeyHQ/cross-inpage-provider",
"license": "Apache-2.0",
"publishConfig": {
"access": "public"
},
"type": "module",
"files": [
"dist/*"
],
"exports": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/cjs/index.js"
},
"types": "./dist/index.d.ts",
"module": "./dist/index.js",
"main": "./dist/cjs/index.js",
"scripts": {
"env": "node dotEnvInit.js",
"report": "yarn env && npx playwright show-report",
"test": "yarn env && npx playwright test ",
"test:headed": "yarn env && npx playwright test --headed ",
"test:ui": "yarn env && npx playwright test --ui "
},
"dependencies": {
"@onekeyfe/cross-inpage-provider-injected": "2.2.6",
"@onekeyfe/cross-inpage-provider-types": "2.2.6",
"@onekeyfe/inpage-providers-hub": "2.2.6",
"lodash-es": "^4.17.21"
},
"devDependencies": {
"@playwright/test": "^1.49.1",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.12.7",
"playwright": "^1.49.1"
}
}
33 changes: 33 additions & 0 deletions packages/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests',
testMatch: ['**/*.e2e.ts', '**/*.e2e.js'],
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [
[
'html',
{
outputFolder: 'playwright-report',
},
],
],
outputDir: 'test-results',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'], viewport: { width: 1440, height: 800 } },
},
{
name: 'Mobile Chrome',
use: { ...devices['iPhone 6'] },
},
],
});
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
64 changes: 64 additions & 0 deletions packages/e2e/tests/bing.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// 在文件顶部添加这个声明
declare global {
interface Window {
$1key: {
hello: () => string;
};
}
}
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved

import { expect, test } from '@playwright/test';

test('Bing search test', async ({ page }) => {
// 打开 Bing
await page.goto('https://www.baidu.com');
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved

// 等待搜索输入框出现并输入内容
const searchInput = page.locator('#kw');
await searchInput.fill('hemoglobin consists of click to select chainsmokers songs');
await searchInput.press('Enter');

// 等待搜索结果出现
await page.waitForSelector('.result.c-container.xpath-log.new-pmd');

// 获取第二个搜索结果
const secondResult = page.locator('.result.c-container.xpath-log.new-pmd').nth(1);

// 使用 evaluate 来高亮元素
await secondResult.evaluate((element) => {
element.style.backgroundColor = 'yellow';
element.style.border = '2px solid red';
});
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved

const init1key = () => {
window.$1key = {
hello: () => 'world',
};
};

// 注入全局变量
await page.evaluate(init1key);

// 验证 $1key 全局变量存在
const hasOneKey = await page.evaluate(() => {
return window.$1key !== undefined;
});
expect(hasOneKey).toBe(true);

// 验证 $1key.hello 方法存在且可调用
const hasHelloMethod = await page.evaluate<string>(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
const result = window.$1key ? window.$1key.hello() : '';
return result;
});
expect(hasHelloMethod).toBe('world');

// 截个图(可选)
await page.screenshot({ path: 'test-results/screenshots/bing-search.png' });

// 验证搜索结果存在
await expect(secondResult).toBeVisible();

// 设置浏览器在测试完成后保持打开状态
// await page.pause();
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { test as base, chromium, type BrowserContext } from '@playwright/test';
import path from 'path';
import env from 'dotenv';
import path from 'path';
const __dirname = path.dirname(new URL(import.meta.url).pathname);
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
env.config({ path: path.resolve(`${__dirname}/../../../../../../../../.env`) });

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { type IInjectedProviderNames } from '@onekeyfe/cross-inpage-provider-types';
import { expect, test } from '@playwright/test';
import path from 'node:path';
import { Locator } from 'playwright/test';
import { sitesConfig } from '../config';
import { createWalletId } from '../utils';
import { expect, test } from './fixtures';

import * as fs from 'fs';

sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
import { connectButtonData } from '@onekeyfe/inpage-providers-hub';

const injectedCode = fs.readFileSync(
path.resolve(
'node_modules/@onekeyfe/cross-inpage-provider-injected/dist/injected/injectedNative.js',
),
'utf-8',
);

sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
const { sitesConfig,createWalletId } = connectButtonData;


const __dirname = path.dirname(new URL(import.meta.url).pathname);
Expand All @@ -14,9 +25,10 @@ async function dbg(locator: Locator) {
}
test.describe('Connect Button Hack', () => {
console.log('total sites:', sitesConfig.length);
const startWebSite = 'app.vesper.finance';
const startIdx = sitesConfig.findIndex((e) => e.urls.includes(startWebSite));
const availableSites = sitesConfig.slice(startIdx == -1 ? 0 : startIdx);
// const startWebSite = 'app.vesper.finance';
// const startIdx = sitesConfig.findIndex((e) => e.urls.includes(startWebSite));
// const availableSites = sitesConfig.slice(startIdx == -1 ? 0 : startIdx);
const availableSites = sitesConfig
const sitesOnly = availableSites.filter((e) => e.only);
const sites = sitesOnly.length > 0 ? sitesOnly : availableSites;
const sitesWithoutSkip = sites.filter((e) => (typeof e.skip === 'boolean' ? !e.skip : true))
Expand All @@ -33,6 +45,7 @@ test.describe('Connect Button Hack', () => {
test(url, async ({ page }, testInfo) => {
const { project: { name }, } = testInfo;
const index = sitesConfig.findIndex((e) => e.urls.includes(url));
// @ts-ignore
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
testInfo['index'] = index;
const device = name.includes('Mobile') ? 'mobile' : 'desktop';
if (typeof skip === 'object' && skip !== null && skip[device] === true) {
Expand All @@ -42,8 +55,13 @@ test.describe('Connect Button Hack', () => {
console.log(`[chrome-devtool]: ${msg.text()}`);
});
await page.goto(`https://${url}`, { waitUntil: 'domcontentloaded' });

// eval injectedCode
await page.evaluate(injectedCode);

sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
if (typeof testPath === 'function') {
await testPath(page as any);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
await testPath(page);
} else {
const actualPath = Array.isArray(testPath) ? testPath : testPath[device] || [];
for (const seg of actualPath) {
Expand All @@ -69,7 +87,12 @@ test.describe('Connect Button Hack', () => {
const locator = page.locator(walletId.walletIdSelector).first();
const existed = await locator.evaluate((el) => !!el );
console.log('[dbg]: walletId found existed', walletId.walletId, existed);
expect(existed).toBeTruthy();

if(!existed){
expect(existed).toBe(walletId.walletIdSelector);
}else{
expect(existed).toBe(true);
}
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
}
}
});
Expand All @@ -78,9 +101,22 @@ test.describe('Connect Button Hack', () => {
//@ts-ignore
test.afterEach(async ({ page }, { project: { name }, status, index }) => {
const isMobile = name.includes('Mobile');
const host = page.url().split('/')[2] || 'passed';
const url = page.url() || 'unknown-url';
let hostname = url;
try {
hostname = new URL(url).hostname;
} catch (error) {
console.error('Failed to parse URL:', error);
}

// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
const screenshotPath = `test-results/screenshots/connectButton/universal/${status}/${index}-${hostname}-${isMobile ? 'mobile' : 'desktop'}-${status}.png`

await page.screenshot({
path: `${__dirname}/screenshots/${index}-${host}-${isMobile ? 'mobile' : 'desktop'}-${status}.png`,
path: screenshotPath,
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
});
});
});


// npx playwright test --headed tests/connectButton/universal.e2e.ts
sidmorizon marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading