From 1e4d7a14edd13ac01be60eef2cc60d752389ed8d Mon Sep 17 00:00:00 2001 From: Christine Pinto Date: Thu, 28 Mar 2024 11:43:37 +0100 Subject: [PATCH 01/18] [ENG-3978] Onboarding UI Test part 1 (#159) Update ESLint to Version 8.40.0 and add ESLint Plugin Playwright Adjust Screensize to 360x360 for CI Add visual check for legal page Add visual check error messages for password pages Skip Backup flow Setup backup and successfully creating a wallet --- .eslintrc.json | 14 +- .github/workflows/playwright.yml | 62 ++--- package-lock.json | 378 ++++++++++++++++------------- package.json | 5 +- playwright.config.ts | 2 +- tests/fixtures/base.ts | 3 +- tests/fixtures/passwordTestData.ts | 37 +++ tests/pages/landing.ts | 23 ++ tests/pages/onboarding.ts | 186 ++++++++++++++ tests/specs/healthcheck.spec.ts | 17 +- tests/specs/onboarding.spec.ts | 166 +++++++++++++ tsconfig.json | 2 +- 12 files changed, 670 insertions(+), 225 deletions(-) create mode 100644 tests/fixtures/passwordTestData.ts create mode 100644 tests/pages/landing.ts create mode 100644 tests/pages/onboarding.ts create mode 100644 tests/specs/onboarding.spec.ts diff --git a/.eslintrc.json b/.eslintrc.json index a82719bf0..95a8db8ab 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,7 +9,8 @@ "airbnb-typescript", "airbnb/hooks", "prettier", - "plugin:@tanstack/eslint-plugin-query/recommended" + "plugin:@tanstack/eslint-plugin-query/recommended", + "plugin:playwright/recommended" ], "parser": "@typescript-eslint/parser", "parserOptions": { @@ -20,10 +21,17 @@ "sourceType": "module", "project": "./tsconfig.json" }, - "plugins": ["react", "prettier", "eslint-plugin-no-inline-styles", "@tanstack/query"], - "ignorePatterns": ["tests/**/*", "playwright.config.ts"], + "plugins": [ + "react", + "prettier", + "eslint-plugin-no-inline-styles", + "@tanstack/query", + "eslint-plugin-playwright" + ], "rules": { "consistent-return": "off", + "no-await-in-loop": "off", + "playwright/valid-title": "off", "import/prefer-default-export": 1, "no-restricted-imports": [ "warn", diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index b69141da6..062c5e1b4 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -11,34 +11,34 @@ jobs: timeout-minutes: 10 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - always-auth: true - node-version: 18 - registry-url: https://npm.pkg.github.com - scope: '@secretkeylabs' - cache: npm - - name: Install dependencies - env: - NODE_AUTH_TOKEN: ${{ secrets.GH_PACKAGE_REGISTRY_TOKEN }} - run: npm ci - - name: Build - env: - TRANSAC_API_KEY: ${{ secrets.TRANSAC_API_KEY }} - MOON_PAY_API_KEY: ${{ secrets.MOON_PAY_API_KEY }} - MIX_PANEL_TOKEN: ${{ secrets.MIX_PANEL_TOKEN }} - run: npm run build --if-present - - name: Install Playwright Browsers - run: npx playwright install chromium --with-deps - - name: Run UI test suite - run: xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" npx playwright test --reporter=html - - name: Upload Playwright report - if: always() - uses: actions/upload-artifact@v3 - with: - name: playwright-report - path: playwright-report/ - retention-days: 30 - \ No newline at end of file + - uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + always-auth: true + node-version: 18 + registry-url: https://npm.pkg.github.com + scope: '@secretkeylabs' + cache: npm + - name: Install dependencies + env: + NODE_AUTH_TOKEN: ${{ secrets.GH_PACKAGE_REGISTRY_TOKEN }} + run: npm ci + - name: Build + env: + TRANSAC_API_KEY: ${{ secrets.TRANSAC_API_KEY }} + MOON_PAY_API_KEY: ${{ secrets.MOON_PAY_API_KEY }} + MIX_PANEL_TOKEN: ${{ secrets.MIX_PANEL_TOKEN }} + MIX_PANEL_EXPLORE_APP_TOKEN: ${{ secrets.MIX_PANEL_EXPLORE_APP_TOKEN }} + run: npm run build --if-present + - name: Install Playwright Browsers + run: npx playwright install chromium --with-deps + - name: Run UI test suite + run: xvfb-run --auto-servernum --server-args="-screen 0 360x360x24" npx playwright test --reporter=html + - name: Upload Playwright report + if: always() + uses: actions/upload-artifact@v3 + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/package-lock.json b/package-lock.json index 2a3d9b897..cd2904dfb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@ledgerhq/hw-transport-webusb": "^6.27.13", "@phosphor-icons/react": "^2.0.10", + "@playwright/test": "^1.42.1", "@react-spring/web": "^9.6.1", "@scure/btc-signer": "1.2.1", "@secretkeylabs/xverse-core": "13.1.0", @@ -79,7 +80,6 @@ "zxcvbn": "^4.4.2" }, "devDependencies": { - "@playwright/test": "^1.42.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", "@tanstack/eslint-plugin-query": "^4.29.4", "@types/argon2-browser": "^1.18.1", @@ -101,13 +101,14 @@ "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.7.1", "dotenv-webpack": "^8.0.1", - "eslint": "8.22.0", + "eslint": "8.40.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^17.0.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-no-inline-styles": "^1.0.5", + "eslint-plugin-playwright": "^1.5.4", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.31.8", "eslint-plugin-react-hooks": "^4.6.0", @@ -790,14 +791,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -813,9 +814,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -839,6 +840,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/js": { + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@floating-ui/core": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz", @@ -862,33 +872,36 @@ "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "engines": { + "node": ">=12.22" + }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "node_modules/@jest/schemas": { @@ -1123,7 +1136,6 @@ "version": "1.42.1", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.42.1.tgz", "integrity": "sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==", - "dev": true, "dependencies": { "playwright": "1.42.1" }, @@ -6188,38 +6200,41 @@ } }, "node_modules/eslint": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", - "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.3", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -6227,11 +6242,9 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -6448,6 +6461,54 @@ "lodash.get": "^4.4.2" } }, + "node_modules/eslint-plugin-playwright": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-1.5.4.tgz", + "integrity": "sha512-J38Wy3Vc2f9y73J+KRmgXgbYI8TZ3zbz6qBbTj3PhpFndUS572jZ7kqQ3rJ9si5BaMHT7lmZzraO+3UjwIDV4Q==", + "dev": true, + "dependencies": { + "globals": "^13.23.0" + }, + "engines": { + "node": ">=16.6.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0", + "eslint-plugin-jest": ">=25" + }, + "peerDependenciesMeta": { + "eslint-plugin-jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-playwright/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-playwright/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-plugin-prettier": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", @@ -6561,33 +6622,6 @@ "node": ">=4.0" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", @@ -6701,6 +6735,15 @@ "node": ">=8" } }, + "node_modules/eslint/node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7377,12 +7420,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -8835,6 +8872,16 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-sdsl": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", + "integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/js-sha256": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.10.1.tgz", @@ -13171,7 +13218,6 @@ "version": "1.42.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.1.tgz", "integrity": "sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==", - "dev": true, "dependencies": { "playwright-core": "1.42.1" }, @@ -13189,7 +13235,6 @@ "version": "1.42.1", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.1.tgz", "integrity": "sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==", - "dev": true, "bin": { "playwright-core": "cli.js" }, @@ -13201,7 +13246,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -14121,18 +14165,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -16015,12 +16047,6 @@ "uuid": "8.3.2" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/valid-url": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", @@ -17342,14 +17368,14 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -17359,9 +17385,9 @@ }, "dependencies": { "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -17375,6 +17401,12 @@ } } }, + "@eslint/js": { + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "dev": true + }, "@floating-ui/core": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz", @@ -17398,26 +17430,26 @@ "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" }, "@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" } }, - "@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "@jest/schemas": { @@ -17605,7 +17637,6 @@ "version": "1.42.1", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.42.1.tgz", "integrity": "sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==", - "dev": true, "requires": { "playwright": "1.42.1" } @@ -21627,38 +21658,41 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "eslint": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", - "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.3", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -21666,11 +21700,9 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "ansi-styles": { @@ -21738,6 +21770,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -21915,6 +21953,32 @@ "lodash.get": "^4.4.2" } }, + "eslint-plugin-playwright": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-1.5.4.tgz", + "integrity": "sha512-J38Wy3Vc2f9y73J+KRmgXgbYI8TZ3zbz6qBbTj3PhpFndUS572jZ7kqQ3rJ9si5BaMHT7lmZzraO+3UjwIDV4Q==", + "dev": true, + "requires": { + "globals": "^13.23.0" + }, + "dependencies": { + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, "eslint-plugin-prettier": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", @@ -21994,23 +22058,6 @@ } } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, "eslint-visitor-keys": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", @@ -22523,12 +22570,6 @@ "functions-have-names": "^1.2.2" } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -23522,6 +23563,12 @@ } } }, + "js-sdsl": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", + "integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==", + "dev": true + }, "js-sha256": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.10.1.tgz", @@ -26523,7 +26570,6 @@ "version": "1.42.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.1.tgz", "integrity": "sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==", - "dev": true, "requires": { "fsevents": "2.3.2", "playwright-core": "1.42.1" @@ -26533,7 +26579,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "optional": true } } @@ -26541,8 +26586,7 @@ "playwright-core": { "version": "1.42.1", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.1.tgz", - "integrity": "sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==", - "dev": true + "integrity": "sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==" }, "postcss": { "version": "8.4.31", @@ -27187,12 +27231,6 @@ "functions-have-names": "^1.2.3" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -28590,12 +28628,6 @@ "uuid": "8.3.2" } }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "valid-url": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", diff --git a/package.json b/package.json index 9cee379c9..e8e4fc1bb 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "nanoid": "^4.0.0", "npm": "10.4.0", "p-queue": "^7.3.4", + "@playwright/test": "^1.42.1", "process": "^0.11.10", "qr-code-styling": "^1.5.0", "rc-image": "^5.14.0", @@ -101,7 +102,6 @@ ] }, "devDependencies": { - "@playwright/test": "^1.42.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", "@tanstack/eslint-plugin-query": "^4.29.4", "@types/argon2-browser": "^1.18.1", @@ -123,13 +123,14 @@ "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.7.1", "dotenv-webpack": "^8.0.1", - "eslint": "8.22.0", + "eslint": "8.40.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^17.0.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-no-inline-styles": "^1.0.5", + "eslint-plugin-playwright": "^1.5.4", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.31.8", "eslint-plugin-react-hooks": "^4.6.0", diff --git a/playwright.config.ts b/playwright.config.ts index fff997b84..6af157aab 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -19,7 +19,7 @@ export default defineConfig({ /* Retry on CI only */ retries: process.env.CI ? 1 : 0, /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : 1, + workers: process.env.CI ? 2 : 1, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: [['list'], ['html']], snapshotDir: './playwright-snapshots', diff --git a/tests/fixtures/base.ts b/tests/fixtures/base.ts index 8323b2f08..cbbb64c5c 100644 --- a/tests/fixtures/base.ts +++ b/tests/fixtures/base.ts @@ -1,6 +1,7 @@ -import { BrowserContext, Page, test as baseTest, chromium } from '@playwright/test'; import path from 'path'; +import { BrowserContext, Page, test as baseTest, chromium } from '@playwright/test'; + export const test = baseTest.extend<{ context: BrowserContext; extensionId: string; diff --git a/tests/fixtures/passwordTestData.ts b/tests/fixtures/passwordTestData.ts new file mode 100644 index 000000000..0da66f7ec --- /dev/null +++ b/tests/fixtures/passwordTestData.ts @@ -0,0 +1,37 @@ +// ToDo: fill with better passworddata +export const passwordTestCases = [ + { + password: '123', + expectations: { + errorMessageVisible: true, + securityLevel: 'Weak', + continueButtonEnabled: false, + }, + }, + { + password: '123456789', + expectations: { + errorMessageVisible: true, + securityLevel: 'Weak', + continueButtonEnabled: false, + }, + }, + { + password: 'Admin@1234', + expectations: { + errorMessageVisible: false, + securityLevel: 'Medium', + continueButtonEnabled: true, + }, + }, + { + password: 'Admin@1234!!', + expectations: { + errorMessageVisible: false, + securityLevel: 'Strong', + continueButtonEnabled: true, + }, + }, +]; + +module.exports = { passwordTestCases }; diff --git a/tests/pages/landing.ts b/tests/pages/landing.ts new file mode 100644 index 000000000..1d3b613e3 --- /dev/null +++ b/tests/pages/landing.ts @@ -0,0 +1,23 @@ +import { Locator, Page, expect } from '@playwright/test'; +// Pageobject for landing page under options.html#/landing +export default class Landing { + readonly buttonCreateWallet: Locator; + + readonly buttonRestoreWallet: Locator; + + readonly landingTitle: Locator; + + constructor(readonly page: Page) { + this.page = page; + this.buttonCreateWallet = page.getByRole('button', { name: 'Create a new wallet' }); + this.buttonRestoreWallet = page.getByRole('button', { name: 'Restore an existing wallet' }); + this.landingTitle = page.getByText('The Bitcoin wallet for everyone'); + } + + // Initialization Method for intial visual check of page object + async initialize() { + await expect(this.buttonCreateWallet).toBeVisible(); + await expect(this.buttonRestoreWallet).toBeVisible(); + await expect(this.landingTitle).toBeVisible(); + } +} diff --git a/tests/pages/onboarding.ts b/tests/pages/onboarding.ts new file mode 100644 index 000000000..f84d42def --- /dev/null +++ b/tests/pages/onboarding.ts @@ -0,0 +1,186 @@ +import { expect, type Locator, type Page } from '@playwright/test'; + +export default class Onboarding { + readonly linkTOS: Locator; + + readonly linkPrivacy: Locator; + + readonly buttonAccept: Locator; + + readonly buttonBackupNow: Locator; + + readonly buttonBackupLater: Locator; + + readonly imageBackup: Locator; + + readonly titleBackupOnboarding: Locator; + + readonly subTitleBackupOnboarding: Locator; + + readonly buttonBack: Locator; + + readonly inputPassword: Locator; + + readonly errorMessage: Locator; + + readonly errorMessage2: Locator; + + readonly buttonContinue: Locator; + + readonly labelSecurityLevelWeak: Locator; + + readonly labelSecurityLevelMedium: Locator; + + readonly labelSecurityLevelStrong: Locator; + + readonly firstParagraphBackupStep: Locator; + + readonly buttonShowSeed: Locator; + + readonly secondParagraphBackupStep: Locator; + + readonly textSeedWords: Locator; + + readonly buttonSeedWords: Locator; + + readonly header: Locator; + + readonly instruction: Locator; + + readonly buttonCloseTab: Locator; + + readonly imageSuccess: Locator; + + constructor(readonly page: Page) { + this.page = page; + this.buttonContinue = page.getByRole('button', { name: 'Continue' }); + this.buttonBack = page.getByRole('button', { name: 'Back' }); + this.buttonBackupNow = page.getByRole('button', { name: 'Backup now' }); + this.buttonBackupLater = page.getByRole('button', { name: 'Backup later' }); + this.imageBackup = page.locator('img[alt="backup"]'); + this.titleBackupOnboarding = page.getByRole('heading', { name: 'Backup' }); + this.subTitleBackupOnboarding = page.getByRole('heading', { name: 'Your seedphrase' }); + this.firstParagraphBackupStep = page.locator('p').filter({ hasText: 'Write down your' }); + this.buttonShowSeed = page.getByRole('button', { name: 'Show' }); + this.secondParagraphBackupStep = page.getByRole('heading', { name: 'Confirm you' }); + this.textSeedWords = page.locator('p[translate="no"]'); + this.buttonSeedWords = page.locator('button[value]:not([value=""])'); + // TODO: find more stable selector + this.header = page.locator('#app h3'); + this.inputPassword = page.locator('input[type="password"]'); + this.errorMessage = page.getByRole('heading', { name: 'Your password should be at' }); + this.errorMessage2 = page.getByRole('heading', { name: 'Please make sure your' }); + this.labelSecurityLevelWeak = page.locator('p').filter({ hasText: 'Weak' }); + this.labelSecurityLevelMedium = page.locator('p').filter({ hasText: 'Medium' }); + this.labelSecurityLevelStrong = page.locator('p').filter({ hasText: 'Strong' }); + this.linkTOS = page.getByRole('link', { name: 'Terms of Service' }); + this.linkPrivacy = page.getByRole('link', { name: 'Privacy Policy' }); + this.buttonAccept = page.getByRole('button', { name: 'Accept' }); + this.imageSuccess = page.locator('img[alt="success"]'); + this.instruction = page.getByRole('heading', { name: 'Locate Xverse' }); + this.buttonCloseTab = page.getByRole('button', { name: 'Close this tab' }); + } + + // TODO add function here for the steps of the onboarding for the case a created wallet should always be created via the UI and is then needed for all following test suits + + // id starts from 0 + inputWord = (id: number) => this.page.locator(`#input${id}`); + + async selectSeedWord(seedWords: string[]): Promise { + const digitsOnly = ((await this.header.last().textContent()) as string).replace(/\D/g, ''); + const seedWord = seedWords[Number(digitsOnly) - 1]; + return seedWord; + } + + async checkLegalPage(context) { + // TODO: Selector outsource + await expect(this.page.locator('div > h1:first-child')).toHaveText(/Legal/); + // check that the links contain href values + // TODO better selectors for link selection + const linkList = this.page.locator('#app a'); + for (let i = 0; i < (await linkList.count()); i++) { + expect(await linkList.nth(i).getAttribute('href')).not.toBeNull(); + } + await expect(this.page.locator('input[type="checkbox"]')).toBeVisible(); + await expect(this.buttonAccept).toBeVisible(); + + // check links + await this.linkTOS.click(); + await context.waitForEvent('page'); + // To check the newest open Tab + let newPage = await context.pages()[context.pages().length - 1]; + await newPage.waitForURL('https://www.xverse.app/terms'); + await newPage.close(); + await this.linkPrivacy.click(); + await context.waitForEvent('page'); + newPage = await context.pages()[context.pages().length - 1]; + await newPage.waitForURL('https://www.xverse.app/privacy'); + await newPage.close(); + } + + async checkBackupPage() { + await expect(this.buttonBackupNow).toBeVisible(); + await expect(this.buttonBackupLater).toBeVisible(); + await expect(this.imageBackup).toBeVisible(); + await expect(this.titleBackupOnboarding).toBeVisible(); + await expect(this.subTitleBackupOnboarding).toBeVisible(); + } + + // Check the viuals on the first password page before inputting any values in the input field + async checkPasswordPage() { + await expect(this.buttonBack).toBeVisible(); + await expect(this.inputPassword).toBeVisible(); + await expect(this.buttonContinue).toBeVisible(); + await expect(this.buttonContinue).toBeDisabled(); + await expect(this.errorMessage).toBeHidden(); + await expect(this.labelSecurityLevelWeak).toBeHidden(); + await expect(this.labelSecurityLevelMedium).toBeHidden(); + await expect(this.labelSecurityLevelStrong).toBeHidden(); + } + + async testPasswordInput({ password, expectations }) { + // Fill in the password input field with the specified password. + await this.inputPassword.fill(password); + + // Check if an error message is expected to be visible. + if (expectations.errorMessageVisible) { + // If yes, verify that the error message element is visible. + await expect(this.errorMessage).toBeVisible(); + } else { + // If not, verify that the error message element is hidden. + await expect(this.errorMessage).toBeHidden(); + } + + // Define a mapping of security levels to their corresponding label elements. + const visibilityChecks = { + Weak: this.labelSecurityLevelWeak, + Medium: this.labelSecurityLevelMedium, + Strong: this.labelSecurityLevelStrong, + }; + + // Concurrently verify the visibility of each security level label. + await Promise.all( + Object.entries(visibilityChecks).map(async ([level, element]) => { + // If the current level matches the expected security level, check that its label is visible. + if (expectations.securityLevel === level) { + await expect(element).toBeVisible(); + } else { + // Otherwise, ensure the label is hidden. + await expect(element).toBeHidden(); + } + }), + ); + + // Check if the continue button is expected to be enabled. + if (expectations.continueButtonEnabled) { + // If yes, verify that the continue button is enabled. + await expect(this.buttonContinue).toBeEnabled(); + } else { + // If not, verify that the continue button is disabled. + await expect(this.buttonContinue).toBeDisabled(); + } + + // Clear the password input field after all checks are done. + await this.inputPassword.clear(); + } +} diff --git a/tests/specs/healthcheck.spec.ts b/tests/specs/healthcheck.spec.ts index 8a617e956..8303e4971 100644 --- a/tests/specs/healthcheck.spec.ts +++ b/tests/specs/healthcheck.spec.ts @@ -1,23 +1,14 @@ -import { expect, test } from '../fixtures/base'; +import { test } from '../fixtures/base'; +import Landing from '../pages/landing'; test.describe('healthcheck', () => { - test.beforeEach(async ({ page, extensionId }) => { - await page.goto(`chrome-extension://${extensionId}/popup.html`); - }); test.afterEach(async ({ context }) => { await context.close(); }); test('healthcheck', async ({ page, extensionId }) => { await page.goto(`chrome-extension://${extensionId}/options.html#/landing`); - //TODO: put texts for selectors into extra file to have one location to maintain them - await expect(page.locator('h1')).toHaveText('The Bitcoin wallet for everyone'); - await expect( - page.getByRole('button', { name: 'Create a new wallet' }), - ).toBeVisible(); - await expect( - page.getByRole('button', { name: 'Restore an existing wallet' }), - ).toBeVisible(); - console.log('healthcheck successfull'); + const landingpage = new Landing(page); + await landingpage.initialize(); }); }); diff --git a/tests/specs/onboarding.spec.ts b/tests/specs/onboarding.spec.ts new file mode 100644 index 000000000..d2128467b --- /dev/null +++ b/tests/specs/onboarding.spec.ts @@ -0,0 +1,166 @@ +import { expect, test } from '../fixtures/base'; +import { passwordTestCases } from '../fixtures/passwordTestData'; +import Landing from '../pages/landing'; +import Onboarding from '../pages/onboarding'; + +// TODO outsoure Password value +const strongPW = 'Admin12345567!!!!'; + +test.describe('onboarding flow', () => { + test.beforeEach(async ({ page, extensionId, context }) => { + await page.goto(`chrome-extension://${extensionId}/options.html#/landing`); + // TODO: this fixes a temporary issue with two tabs at the start see technical debt https://linear.app/xverseapp/issue/ENG-3992/two-tabs-open-instead-of-one-since-version-0323-for-start-extension + const pages = await context.pages(); + if (pages.length === 2) { + await pages[1].close(); // pages[1] is the second (newest) page + } + }); + test.afterEach(async ({ context }) => { + if (context.pages().length > 0) { + // Close the context only if there are open pages + await context.close(); + } + }); + + test('visual check legal page', async ({ page, context }) => { + const landingpage = new Landing(page); + + // Click on create Wallet and check legal page elements + await landingpage.buttonCreateWallet.click(); + const onboardingpage = new Onboarding(page); + await expect(page.url()).toContain('legal'); + await onboardingpage.checkLegalPage(context); + }); + + // Visual check of the first page for backup + test('visual check backup page main', async ({ page }) => { + const landingpage = new Landing(page); + + await landingpage.buttonCreateWallet.click(); + const onboardingpage = new Onboarding(page); + await expect(page.url()).toContain('legal'); + await onboardingpage.buttonAccept.click(); + await expect(page.url()).toContain('backup'); + await onboardingpage.checkBackupPage(); + }); + + // Visual check of the first page for password creation + test('skip backup and visual check password page', async ({ page }) => { + const landingpage = new Landing(page); + + await landingpage.buttonCreateWallet.click(); + const onboardingpage = new Onboarding(page); + await expect(page.url()).toContain('legal'); + await onboardingpage.buttonAccept.click(); + await expect(page.url()).toContain('backup'); + await onboardingpage.buttonBackupLater.click(); + await expect(page.url()).toContain('create-password'); + await onboardingpage.checkPasswordPage(); + await onboardingpage.buttonBack.click(); + await expect(page.url()).toContain('backup'); + }); + + // No Wallet is created in this step as we only check the display of the error messages and that you can't create a wallet if passwords don't align + test('Skip backup and check password error messages', async ({ page }) => { + const landingpage = new Landing(page); + + await landingpage.buttonCreateWallet.click(); + const onboardingpage = new Onboarding(page); + await expect(page.url()).toContain('legal'); + await onboardingpage.buttonAccept.click(); + await expect(page.url()).toContain('backup'); + await onboardingpage.buttonBackupLater.click(); + await expect(page.url()).toContain('create-password'); + + // Check error message, security label change, and status of continue button + await passwordTestCases.reduce(async (previousPromise, testCase) => { + await previousPromise; + return onboardingpage.testPasswordInput(testCase); + }, Promise.resolve()); + + await onboardingpage.inputPassword.fill(strongPW); + await onboardingpage.buttonContinue.click(); + // check Confirm header + await expect(page.locator('h1')).toHaveText(/confirm/i); + // Enter wrong password to check error messages + await expect(onboardingpage.buttonContinue).toBeDisabled(); + await onboardingpage.inputPassword.fill(`${strongPW}123`); + await expect(onboardingpage.buttonContinue).toBeEnabled(); + await onboardingpage.buttonContinue.click(); + await expect(onboardingpage.errorMessage2).toBeVisible(); + // multiple times clicking on continue to check that the user stays on the page and can't continue even of clicked multiple times + await onboardingpage.buttonContinue.click(); + await onboardingpage.buttonContinue.click(); + await onboardingpage.buttonContinue.click(); + await expect(onboardingpage.errorMessage2).toBeVisible(); + await onboardingpage.buttonBack.click(); + await expect(onboardingpage.inputPassword).toHaveValue(/.+/); + await onboardingpage.buttonContinue.click(); + await expect(onboardingpage.inputPassword).toHaveValue(/.+/); + await expect(onboardingpage.errorMessage2).toBeVisible(); + }); + + test('backup seedphrase and successfully create a wallet', async ({ page, context }) => { + const landingpage = new Landing(page); + + await landingpage.buttonCreateWallet.click(); + const onboardingpage = new Onboarding(page); + await expect(page.url()).toContain('legal'); + await onboardingpage.buttonAccept.click(); + await expect(page.url()).toContain('backup'); + await onboardingpage.buttonBackupNow.click(); + await expect(page.url()).toContain('backupWalletSteps'); + await expect(onboardingpage.buttonContinue).toBeDisabled(); + await expect(onboardingpage.buttonShowSeed).toBeVisible(); + await expect(onboardingpage.firstParagraphBackupStep).toBeVisible(); + await onboardingpage.buttonShowSeed.click(); + await expect(onboardingpage.buttonContinue).toBeEnabled(); + const seedWords = await onboardingpage.textSeedWords.allTextContents(); + await onboardingpage.buttonContinue.click(); + + // check if 12 words are displayed + await expect(onboardingpage.buttonSeedWords).toHaveCount(12); + await expect(onboardingpage.secondParagraphBackupStep).toBeVisible(); + let seedword = await onboardingpage.selectSeedWord(seedWords); + + // get all displayed values and filter the value from the actual seedphrase out to do an error message check + const buttonValues = await onboardingpage.buttonSeedWords.evaluateAll((buttons) => + buttons.map((button) => { + // Assert that the button is an HTMLButtonElement to access the `value` property + if (button instanceof HTMLButtonElement) { + return button.value; + } + return 'testvalue'; + }), + ); + + const filteredValues = buttonValues.filter((value) => value !== seedword); + const randomValue = filteredValues[Math.floor(Math.random() * filteredValues.length)]; + await page.locator(`button[value="${randomValue}"]`).click(); + + // Check if error message is displayed when clicking the wrong seedword + await expect(page.locator('p:has-text("This word is not")')).toBeVisible(); + + await page.locator(`button[value="${seedword}"]`).click(); + seedword = await onboardingpage.selectSeedWord(seedWords); + await page.locator(`button[value="${seedword}"]`).click(); + seedword = await onboardingpage.selectSeedWord(seedWords); + await page.locator(`button[value="${seedword}"]`).click(); + + // TODO: currently the error messages as not shown for the passwords in this step so this check needs to be commment out until it is fixed + /* for (const testCase of passwordTestCases) { + await onboardingpage.testPasswordInput(testCase); + } */ + + await onboardingpage.inputPassword.fill(strongPW); + await onboardingpage.buttonContinue.click(); + await onboardingpage.inputPassword.fill(strongPW); + await onboardingpage.buttonContinue.click(); + + await expect(onboardingpage.imageSuccess).toBeVisible(); + await expect(onboardingpage.instruction).toBeVisible(); + await expect(onboardingpage.buttonCloseTab).toBeVisible(); + await onboardingpage.buttonCloseTab.click(); + expect(context.pages()).toHaveLength(0); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index c79850888..d94c7348d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -31,5 +31,5 @@ "@ui-components/*": ["app/ui-components/*"] } }, - "include": ["src", "styled.d.ts"] + "include": ["src", "tests", "styled.d.ts", "playwright.config.ts"] } From f9ffbba547ac80204a246a6edc9f5da946ac3e33 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Tue, 2 Apr 2024 14:47:13 +0800 Subject: [PATCH 02/18] [ENG-3808] chore: script merge public to private (#155) * chore: add a script for merging public to private chore: update merge scripts chore: update scripts with correct remote url chore: fix gh cli check in scirpts chore: fix scripts with pr command chore: fix new lines chore: fix attempt for the release pr action error: fatal unrelated histories chore: add workflow to trigger the script chore: remove trigger on pr chore: rename workflow and add choice of direction chore: update script with --unshallow chore: remove --unshallow chore: simplify merge script chore: delete other script in favour of one way merges chore: continue script if bad tags chore: assign reviewers to the merge chore: fix assign reviewer part chore: oops remove merge markers chore: loop for main and develop chore: add script use to workflows chore: remove unshallow for --allow-unrelated-histories chore: remove comment * chore: use a generic name for merge script * chore: add CODEOWNERS file * chore: fix asset upload and add steps to copy release to public --- .github/CODEOWNERS | 1 + .github/workflows/merge-repos.yml | 33 +++++++++++++ .github/workflows/release-develop.yml | 33 +++++++++++++ .github/workflows/release.yml | 46 +++++++++++++++++- scripts/.gitignore | 2 +- scripts/create-release-pr.sh | 4 +- scripts/merge-to-remote.sh | 70 +++++++++++++++++++++++++++ 7 files changed, 185 insertions(+), 4 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/workflows/merge-repos.yml create mode 100644 .github/workflows/release-develop.yml create mode 100755 scripts/merge-to-remote.sh diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..2b1e0903d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @secretkeylabs/reviewers-web-extension diff --git a/.github/workflows/merge-repos.yml b/.github/workflows/merge-repos.yml new file mode 100644 index 000000000..383ba0364 --- /dev/null +++ b/.github/workflows/merge-repos.yml @@ -0,0 +1,33 @@ +name: Merge branch to remote + +on: + workflow_dispatch: + inputs: + branch: + description: 'Merge branch' + required: true + default: develop + type: choice + options: + - develop + - main + +jobs: + merge-branch-to-remote: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/checkout@v4 + - id: run-merge-script + env: + ORIGIN_BRANCH: ${{ inputs.branch }} + GH_TOKEN: ${{ github.token }} + REMOTE_REPO: ${{ secrets.REMOTE_REPO }} + run: | + # git config + git config user.name "GitHub Actions Bot" + git config user.email "<>" + # run shell script + cd scripts + ORIGIN_BRANCH=$ORIGIN_BRANCH REMOTE_REPO=$REMOTE_REPO ./merge-to-remote.sh diff --git a/.github/workflows/release-develop.yml b/.github/workflows/release-develop.yml new file mode 100644 index 000000000..71ddbaac5 --- /dev/null +++ b/.github/workflows/release-develop.yml @@ -0,0 +1,33 @@ +name: Merge release to develop +## +# This workflow triggers on merge of release branch back to develop +# +# It should push to public repo +# +on: + pull_request: + branches: + - develop + types: + - closed +jobs: + publish-latest: + if: ${{ github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/')}} + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + env: + GH_TOKEN: ${{ github.token }} + steps: + - uses: actions/checkout@v4 + - id: push-to-public + name: Push to public remote + if: ${{ contains(github.repositoryUrl, 'private' }} + run: | + # git config + git config user.name "GitHub Actions Bot" + git config user.email "<>" + # run shell script + cd scripts + ORIGIN_BRANCH=develop REMOTE_REPO=xverse-web-extension ./merge-to-remote.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9401e3cdc..65894d566 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,6 +29,7 @@ jobs: env: SOURCE_BRANCH: ${{ github.head_ref }} run: | + cd scripts # find the target commitish of the latest release matching our tag TAG=$(echo $SOURCE_BRANCH | sed 's/release\/\(.*\)/\1/') gh api \ @@ -48,6 +49,8 @@ jobs: -f name="$TAG" \ -F generate_release_notes=true > release.json # save env for upload + echo "TAG=$TAG" >> $GITHUB_ENV + echo "TARGET_COMMITISH=$TARGET_COMMITISH" >> $GITHUB_ENV echo "TAG_RC=$TAG_RC" >> $GITHUB_ENV echo "FILENAME=xverse-web-extension.$TAG.zip" >> $GITHUB_ENV echo "UPLOAD_URL=$(cat release.json | jq -r .upload_url)" >> $GITHUB_ENV @@ -68,11 +71,11 @@ jobs: - id: download-latest-asset name: Download latest asset from rc run: | - RELEASE_ID=$(cat releases.json | jq -r ".[] | select(.tag_name==\"$TAG_RC\") | .id") + ASSET_ID=$(cat releases.json | jq -r ".[] | select(.tag_name==\"$TAG_RC\") | .assets[0].id") gh api \ -H "Accept: application/octet-stream" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/{owner}/{repo}/releases/assets/$RELEASE_ID > build.zip + /repos/{owner}/{repo}/releases/assets/$ASSET_ID > build.zip - id: upload-latest-asset name: Upload latest asset to latest release uses: actions/upload-release-asset@v1 @@ -83,3 +86,42 @@ jobs: asset_path: build.zip asset_name: ${{ env.FILENAME }} asset_content_type: application/zip + - id: push-to-public + name: Push to public remote + if: ${{ contains(github.repositoryUrl, 'private' }} + env: + REMOTE_REPO: xverse-web-extension + run: | + # git config + git config user.name "GitHub Actions Bot" + git config user.email "<>" + # run shell script + ./merge-to-remote.sh + - id: copy-release-to-public + name: Copy release to public remote + needs: push-to-public + env: + REMOTE_REPO: xverse-web-extension + run: | + # publish the latest release on remote + cat release.json | jq -r .body > public-body.md + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/{owner}/$REMOTE_REPO/releases \ + -f tag_name="$TAG" \ + -f target_commitish="$TARGET_COMMITISH" \ + -f name="$TAG" \ + -F 'body=@public-body.md' > public-release.json + echo "PUBLIC_UPLOAD_URL=$(cat public-release.json | jq -r .upload_url)" >> $GITHUB_ENV + - id: upload-latest-asset-to-public + name: Upload latest asset to latest release on public remote + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ env.PUBLIC_UPLOAD_URL}} + asset_path: build.zip + asset_name: ${{ env.FILENAME }} + asset_content_type: application/zip diff --git a/scripts/.gitignore b/scripts/.gitignore index 3f4dae6b5..c1ddfd3d5 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -1,4 +1,4 @@ release.json -pr-*.json +pr*.json body.md releases.json diff --git a/scripts/create-release-pr.sh b/scripts/create-release-pr.sh index 267c41b0d..c9d7a9b07 100755 --- a/scripts/create-release-pr.sh +++ b/scripts/create-release-pr.sh @@ -7,6 +7,8 @@ # Alternatively trigger it from the github action # +set -e + if [[ -z "$BUMP" ]]; then echo "BUMP is required. major|minor|patch" exit 1 @@ -26,7 +28,7 @@ TITLE="release: $TAG" git checkout -B $BRANCH git commit -am "$TITLE" -git merge origin/main -s ours +git merge --allow-unrelated-histories origin/main -s ours git push --set-upstream origin $BRANCH diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh new file mode 100755 index 000000000..93c960765 --- /dev/null +++ b/scripts/merge-to-remote.sh @@ -0,0 +1,70 @@ +#! /bin/bash + +## +# merge-to-remote.sh +# +# to be run locally from downstream repo, or from GitHub Actions + +set -e + +if [[ -z $(git status --porcelain) ]]; then + echo "Working directory clean. Proceeding with merge." +else + echo "Working directory not clean. Please commit or stash your changes before proceeding." + exit 1 +fi + +ORIGIN_BRANCH=${ORIGIN_BRANCH:-main} # defaults to main +REMOTE_REPO=${REMOTE_REPO:-xverse-web-extension} # defaults to xverse-web-extension + +echo "Merging $ORIGIN_BRANCH to $REMOTE_REPO" + +ORIGIN_NAME="origin" +REMOTE_URL="git@github.com:secretkeylabs/$REMOTE_REPO.git" +REMOTE_NAME="public" + +## add or set remote +git remote -v | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL +git remote set-url $REMOTE_NAME $REMOTE_URL + +## fetch from all remotes including tags +git fetch --all --tags || true # TODO remove || true after fixing tag conflicts + +PR_TITLE="merge-$ORIGIN_BRANCH-to-$REMOTE_NAME" +REMOTE_BRANCH="chore/$PR_TITLE-$(date +%s)" +REMOTE_BASE=$ORIGIN_BRANCH + +## checkout origin branch and push to remote +echo "Checking out $ORIGIN_NAME/$ORIGIN_BRANCH and pushing to $REMOTE_NAME/$REMOTE_BRANCH" +git checkout $ORIGIN_NAME/$ORIGIN_BRANCH +git checkout -B $REMOTE_BRANCH +git push $REMOTE_NAME $REMOTE_BRANCH + +if command -v gh >/dev/null 2>&1; then + echo "gh cli installed. Proceeding with PR creation." +else + echo "gh cli not installed. Please install gh cli or create the PR manually." + exit 1 +fi + +## create PR and assign team review +gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/{owner}/$REMOTE_REPO/pulls \ + -f title="$PR_TITLE" \ + -f head="$REMOTE_BRANCH" \ + -f base="$REMOTE_BASE" \ + -f body="Created by merge-to-remote.sh" > pr.json + +PULL_NUMBER=$(jq -r '.number' pr.json) +gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/{owner}/$REMOTE_REPO/pulls/$PULL_NUMBER/requested_reviewers \ +-f "team_reviewers[]=reviewers-web-extension" + +## push tags +git push $REMOTE_NAME --tags || true # TODO remove || true after fixing tag conflicts From 0da55eeb95c3e350a4abf70722436e878ca16018 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Tue, 2 Apr 2024 15:05:45 +0800 Subject: [PATCH 03/18] chore: fix release develop workflow file (#167) --- .github/workflows/release-develop.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-develop.yml b/.github/workflows/release-develop.yml index 71ddbaac5..0d4765211 100644 --- a/.github/workflows/release-develop.yml +++ b/.github/workflows/release-develop.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v4 - id: push-to-public name: Push to public remote - if: ${{ contains(github.repositoryUrl, 'private' }} + if: ${{ contains(github.repositoryUrl, 'private') }} run: | # git config git config user.name "GitHub Actions Bot" From 5da5a1ba9218a9cbc0dc1a560cf8ce1e843d6196 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Tue, 2 Apr 2024 15:48:04 +0800 Subject: [PATCH 04/18] chore: fix merge repos workflow permissions --- .github/workflows/merge-repos.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/merge-repos.yml b/.github/workflows/merge-repos.yml index 383ba0364..b57054383 100644 --- a/.github/workflows/merge-repos.yml +++ b/.github/workflows/merge-repos.yml @@ -17,6 +17,7 @@ jobs: runs-on: ubuntu-latest permissions: pull-requests: write + contents: write steps: - uses: actions/checkout@v4 - id: run-merge-script From ce08b8766324a6db7227215930a603648cd23c0b Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 11:31:16 +0800 Subject: [PATCH 05/18] chore: use https git remote url when on CI --- scripts/merge-to-remote.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index 93c960765..bc7c854d1 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -20,7 +20,7 @@ REMOTE_REPO=${REMOTE_REPO:-xverse-web-extension} # defaults to xverse-web-extens echo "Merging $ORIGIN_BRANCH to $REMOTE_REPO" ORIGIN_NAME="origin" -REMOTE_URL="git@github.com:secretkeylabs/$REMOTE_REPO.git" +REMOTE_URL=$((CI ? "https://github.com/secretkeylabs/$REMOTE_REPO" : "git@github.com:secretkeylabs/$REMOTE_REPO.git" )) REMOTE_NAME="public" ## add or set remote From df25a7c6c797abb99f31fca4989ff365b89a3d82 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 11:40:40 +0800 Subject: [PATCH 06/18] chore: fix merge git remote ternary --- scripts/merge-to-remote.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index bc7c854d1..1529f17f6 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -20,10 +20,15 @@ REMOTE_REPO=${REMOTE_REPO:-xverse-web-extension} # defaults to xverse-web-extens echo "Merging $ORIGIN_BRANCH to $REMOTE_REPO" ORIGIN_NAME="origin" -REMOTE_URL=$((CI ? "https://github.com/secretkeylabs/$REMOTE_REPO" : "git@github.com:secretkeylabs/$REMOTE_REPO.git" )) +REMOTE_URL="git@github.com:secretkeylabs/$REMOTE_REPO.git" +if [[ $CI == "true" ]]; then + REMOTE_URL="https://github.com/secretkeylabs/$REMOTE_REPO" +fi REMOTE_NAME="public" + ## add or set remote +echo Add or set $REMOTE_NAME $REMOTE_URL git remote -v | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL git remote set-url $REMOTE_NAME $REMOTE_URL From ba3a57e3f656bcdcaf78450f8a86f8b8fdd5a429 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 11:40:40 +0800 Subject: [PATCH 07/18] chore: fix merge git remote ternary --- scripts/merge-to-remote.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index bc7c854d1..1529f17f6 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -20,10 +20,15 @@ REMOTE_REPO=${REMOTE_REPO:-xverse-web-extension} # defaults to xverse-web-extens echo "Merging $ORIGIN_BRANCH to $REMOTE_REPO" ORIGIN_NAME="origin" -REMOTE_URL=$((CI ? "https://github.com/secretkeylabs/$REMOTE_REPO" : "git@github.com:secretkeylabs/$REMOTE_REPO.git" )) +REMOTE_URL="git@github.com:secretkeylabs/$REMOTE_REPO.git" +if [[ $CI == "true" ]]; then + REMOTE_URL="https://github.com/secretkeylabs/$REMOTE_REPO" +fi REMOTE_NAME="public" + ## add or set remote +echo Add or set $REMOTE_NAME $REMOTE_URL git remote -v | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL git remote set-url $REMOTE_NAME $REMOTE_URL From be1fe66dafe063e72dddb26a91a410fe217dbf02 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 13:21:24 +0800 Subject: [PATCH 08/18] chore: fix permissions for merge --- .github/workflows/merge-repos.yml | 2 +- scripts/merge-to-remote.sh | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/merge-repos.yml b/.github/workflows/merge-repos.yml index b57054383..17da4684f 100644 --- a/.github/workflows/merge-repos.yml +++ b/.github/workflows/merge-repos.yml @@ -23,8 +23,8 @@ jobs: - id: run-merge-script env: ORIGIN_BRANCH: ${{ inputs.branch }} - GH_TOKEN: ${{ github.token }} REMOTE_REPO: ${{ secrets.REMOTE_REPO }} + GH_TOKEN: ${{ secrets.GH_REPOS_RW_PAT }} run: | # git config git config user.name "GitHub Actions Bot" diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index 1529f17f6..d2bc4f954 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -22,13 +22,12 @@ echo "Merging $ORIGIN_BRANCH to $REMOTE_REPO" ORIGIN_NAME="origin" REMOTE_URL="git@github.com:secretkeylabs/$REMOTE_REPO.git" if [[ $CI == "true" ]]; then - REMOTE_URL="https://github.com/secretkeylabs/$REMOTE_REPO" + REMOTE_URL="https://x-access-token:${GH_TOKEN}@github.com/secretkeylabs/$REMOTE_REPO" fi REMOTE_NAME="public" ## add or set remote -echo Add or set $REMOTE_NAME $REMOTE_URL git remote -v | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL git remote set-url $REMOTE_NAME $REMOTE_URL From b86f0aa1192b18796f863ecf2f432ed6c602fd74 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 13:21:24 +0800 Subject: [PATCH 09/18] chore: fix permissions for merge --- .github/workflows/merge-repos.yml | 2 +- scripts/merge-to-remote.sh | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/merge-repos.yml b/.github/workflows/merge-repos.yml index b57054383..17da4684f 100644 --- a/.github/workflows/merge-repos.yml +++ b/.github/workflows/merge-repos.yml @@ -23,8 +23,8 @@ jobs: - id: run-merge-script env: ORIGIN_BRANCH: ${{ inputs.branch }} - GH_TOKEN: ${{ github.token }} REMOTE_REPO: ${{ secrets.REMOTE_REPO }} + GH_TOKEN: ${{ secrets.GH_REPOS_RW_PAT }} run: | # git config git config user.name "GitHub Actions Bot" diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index 1529f17f6..d2bc4f954 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -22,13 +22,12 @@ echo "Merging $ORIGIN_BRANCH to $REMOTE_REPO" ORIGIN_NAME="origin" REMOTE_URL="git@github.com:secretkeylabs/$REMOTE_REPO.git" if [[ $CI == "true" ]]; then - REMOTE_URL="https://github.com/secretkeylabs/$REMOTE_REPO" + REMOTE_URL="https://x-access-token:${GH_TOKEN}@github.com/secretkeylabs/$REMOTE_REPO" fi REMOTE_NAME="public" ## add or set remote -echo Add or set $REMOTE_NAME $REMOTE_URL git remote -v | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL git remote set-url $REMOTE_NAME $REMOTE_URL From a6a40a8fc350c73f64fdc83ffc257824f16e0db1 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 13:58:35 +0800 Subject: [PATCH 10/18] chore: only fetch the branch to be merged --- scripts/merge-to-remote.sh | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index d2bc4f954..1165680d9 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -32,7 +32,8 @@ git remote -v | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL git remote set-url $REMOTE_NAME $REMOTE_URL ## fetch from all remotes including tags -git fetch --all --tags || true # TODO remove || true after fixing tag conflicts +git fetch $ORIGIN_NAME $ORIGIN_BRANCH --tags || true # TODO remove || true after fixing tag conflicts +git fetch $REMOTE_NAME $ORIGIN_BRANCH --tags || true # TODO remove || true after fixing tag conflicts PR_TITLE="merge-$ORIGIN_BRANCH-to-$REMOTE_NAME" REMOTE_BRANCH="chore/$PR_TITLE-$(date +%s)" @@ -62,13 +63,5 @@ gh api \ -f base="$REMOTE_BASE" \ -f body="Created by merge-to-remote.sh" > pr.json -PULL_NUMBER=$(jq -r '.number' pr.json) -gh api \ - --method POST \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/{owner}/$REMOTE_REPO/pulls/$PULL_NUMBER/requested_reviewers \ --f "team_reviewers[]=reviewers-web-extension" - ## push tags git push $REMOTE_NAME --tags || true # TODO remove || true after fixing tag conflicts From ffb71da4eac8afaadbdc5a667ff533055acf7a7d Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 13:58:35 +0800 Subject: [PATCH 11/18] chore: only fetch the branch to be merged --- scripts/merge-to-remote.sh | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index d2bc4f954..1165680d9 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -32,7 +32,8 @@ git remote -v | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL git remote set-url $REMOTE_NAME $REMOTE_URL ## fetch from all remotes including tags -git fetch --all --tags || true # TODO remove || true after fixing tag conflicts +git fetch $ORIGIN_NAME $ORIGIN_BRANCH --tags || true # TODO remove || true after fixing tag conflicts +git fetch $REMOTE_NAME $ORIGIN_BRANCH --tags || true # TODO remove || true after fixing tag conflicts PR_TITLE="merge-$ORIGIN_BRANCH-to-$REMOTE_NAME" REMOTE_BRANCH="chore/$PR_TITLE-$(date +%s)" @@ -62,13 +63,5 @@ gh api \ -f base="$REMOTE_BASE" \ -f body="Created by merge-to-remote.sh" > pr.json -PULL_NUMBER=$(jq -r '.number' pr.json) -gh api \ - --method POST \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/{owner}/$REMOTE_REPO/pulls/$PULL_NUMBER/requested_reviewers \ --f "team_reviewers[]=reviewers-web-extension" - ## push tags git push $REMOTE_NAME --tags || true # TODO remove || true after fixing tag conflicts From 37560a99fcf354a130da5916fae4e7d1f590ff9d Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 14:26:08 +0800 Subject: [PATCH 12/18] chore: try using GITHUB_ACTIONS env var --- scripts/merge-to-remote.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index 1165680d9..fffe42f98 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -21,14 +21,14 @@ echo "Merging $ORIGIN_BRANCH to $REMOTE_REPO" ORIGIN_NAME="origin" REMOTE_URL="git@github.com:secretkeylabs/$REMOTE_REPO.git" -if [[ $CI == "true" ]]; then +if [[ $GITHUB_ACTIONS == "true" ]]; then REMOTE_URL="https://x-access-token:${GH_TOKEN}@github.com/secretkeylabs/$REMOTE_REPO" fi REMOTE_NAME="public" ## add or set remote -git remote -v | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL +git remote | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL git remote set-url $REMOTE_NAME $REMOTE_URL ## fetch from all remotes including tags From 70eeac22d22d8120d8faa2c2b3b65c365745aeb4 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 14:31:12 +0800 Subject: [PATCH 13/18] chore: add debug echo --- scripts/merge-to-remote.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index fffe42f98..6ff9f9300 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -22,6 +22,7 @@ echo "Merging $ORIGIN_BRANCH to $REMOTE_REPO" ORIGIN_NAME="origin" REMOTE_URL="git@github.com:secretkeylabs/$REMOTE_REPO.git" if [[ $GITHUB_ACTIONS == "true" ]]; then + echo "Running in GitHub Actions. Using GitHub token for authentication." REMOTE_URL="https://x-access-token:${GH_TOKEN}@github.com/secretkeylabs/$REMOTE_REPO" fi REMOTE_NAME="public" From 5b9ecde2be97996216236c3d314586de3fb09112 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 14:41:45 +0800 Subject: [PATCH 14/18] chore: debug remotes --- scripts/merge-to-remote.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index 6ff9f9300..39b984e9a 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -31,6 +31,9 @@ REMOTE_NAME="public" ## add or set remote git remote | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL git remote set-url $REMOTE_NAME $REMOTE_URL +git remote -v +git remote set-url --push $REMOTE_NAME $REMOTE_URL +git remote -v ## fetch from all remotes including tags git fetch $ORIGIN_NAME $ORIGIN_BRANCH --tags || true # TODO remove || true after fixing tag conflicts From d0cb273ca5d36a9f24788441c82035c095ded179 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 14:57:41 +0800 Subject: [PATCH 15/18] chore: debug push --- scripts/merge-to-remote.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/merge-to-remote.sh b/scripts/merge-to-remote.sh index 39b984e9a..3ac55242b 100755 --- a/scripts/merge-to-remote.sh +++ b/scripts/merge-to-remote.sh @@ -23,7 +23,7 @@ ORIGIN_NAME="origin" REMOTE_URL="git@github.com:secretkeylabs/$REMOTE_REPO.git" if [[ $GITHUB_ACTIONS == "true" ]]; then echo "Running in GitHub Actions. Using GitHub token for authentication." - REMOTE_URL="https://x-access-token:${GH_TOKEN}@github.com/secretkeylabs/$REMOTE_REPO" + REMOTE_URL="https://${GH_TOKEN}@github.com/secretkeylabs/$REMOTE_REPO" fi REMOTE_NAME="public" @@ -31,7 +31,6 @@ REMOTE_NAME="public" ## add or set remote git remote | grep -w $REMOTE_NAME || git remote add $REMOTE_NAME $REMOTE_URL git remote set-url $REMOTE_NAME $REMOTE_URL -git remote -v git remote set-url --push $REMOTE_NAME $REMOTE_URL git remote -v @@ -47,7 +46,7 @@ REMOTE_BASE=$ORIGIN_BRANCH echo "Checking out $ORIGIN_NAME/$ORIGIN_BRANCH and pushing to $REMOTE_NAME/$REMOTE_BRANCH" git checkout $ORIGIN_NAME/$ORIGIN_BRANCH git checkout -B $REMOTE_BRANCH -git push $REMOTE_NAME $REMOTE_BRANCH +git push -v $REMOTE_NAME $REMOTE_BRANCH if command -v gh >/dev/null 2>&1; then echo "gh cli installed. Proceeding with PR creation." @@ -56,7 +55,7 @@ else exit 1 fi -## create PR and assign team review +## create PR gh api \ --method POST \ -H "Accept: application/vnd.github+json" \ From 0a05d42bd418debee9ef1ad83ae4faf2a92b78b1 Mon Sep 17 00:00:00 2001 From: Tim Man Date: Wed, 3 Apr 2024 17:37:39 +0800 Subject: [PATCH 16/18] fix: never generate wallet from random seed phrase (#158) --- src/app/components/passwordInput/index.tsx | 16 +++---- src/app/hooks/useWalletReducer.ts | 9 ++-- src/app/screens/backupWallet/index.tsx | 2 +- src/app/screens/backupWalletSteps/index.tsx | 5 +- src/app/screens/createPassword/index.tsx | 6 +-- src/app/screens/landing/index.tsx | 51 +++++++++++---------- 6 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/app/components/passwordInput/index.tsx b/src/app/components/passwordInput/index.tsx index f86fccde5..6e406da31 100644 --- a/src/app/components/passwordInput/index.tsx +++ b/src/app/components/passwordInput/index.tsx @@ -25,8 +25,8 @@ interface PasswordInputProps { } interface StrengthBarProps { - strengthColor: string; - strengthWidth: string; + $strengthColor: string; + $strengthWidth: string; } const Container = styled.div({ @@ -131,9 +131,9 @@ const StrengthBar = styled(animated.div)((props) => ({ borderRadius: props.theme.radius(1), width: '50%', div: { - width: props.strengthWidth, + width: props.$strengthWidth, height: 4, - backgroundColor: props.strengthColor, + backgroundColor: props.$strengthColor, borderRadius: props.theme.radius(1), }, })); @@ -250,7 +250,7 @@ function PasswordInput(props: PasswordInputProps): JSX.Element { return ( {t('PASSWORD_STRENGTH_LABEL')} - + {transition((style) => ( ))} @@ -265,7 +265,7 @@ function PasswordInput(props: PasswordInputProps): JSX.Element { {t('PASSWORD_STRENGTH_LABEL')} {transition((style) => ( - + ))} @@ -278,7 +278,7 @@ function PasswordInput(props: PasswordInputProps): JSX.Element { {t('PASSWORD_STRENGTH_LABEL')} {transition((style) => ( - + ))} @@ -289,7 +289,7 @@ function PasswordInput(props: PasswordInputProps): JSX.Element { return ( {t('PASSWORD_STRENGTH_LABEL')} - + {transition((style) => ( ))} diff --git a/src/app/hooks/useWalletReducer.ts b/src/app/hooks/useWalletReducer.ts index d4fe25249..0d655a994 100644 --- a/src/app/hooks/useWalletReducer.ts +++ b/src/app/hooks/useWalletReducer.ts @@ -246,10 +246,11 @@ const useWalletReducer = () => { } }; - const createWallet = async (mnemonic?: string) => { - const wallet = mnemonic - ? await walletFromSeedPhrase({ mnemonic, index: 0n, network: 'Mainnet' }) - : await newWallet(); + const createWallet = async () => { + const mnemonic = await seedVault.getSeed(); + // TODO refactor to use createWalletAccount instead, which also adds bns name + // and gaiahub config + const wallet = await walletFromSeedPhrase({ mnemonic, index: 0n, network: 'Mainnet' }); const account: Account = { id: 0, diff --git a/src/app/screens/backupWallet/index.tsx b/src/app/screens/backupWallet/index.tsx index dff5d96d1..e7734795d 100644 --- a/src/app/screens/backupWallet/index.tsx +++ b/src/app/screens/backupWallet/index.tsx @@ -1,5 +1,4 @@ import backup from '@assets/img/backupWallet/backup.svg'; -import ActionButton from '@components/button'; import useSeedVault from '@hooks/useSeedVault'; import { generateMnemonic } from '@secretkeylabs/xverse-core'; import Button from '@ui-library/button'; @@ -62,6 +61,7 @@ function BackupWallet(): JSX.Element { clearVaultStorage, } = useSeedVault(); + // TODO move this to SeedVault? const generateAndStoreSeedPhrase = async () => { const newSeedPhrase = generateMnemonic(); await initSeedVault(''); diff --git a/src/app/screens/backupWalletSteps/index.tsx b/src/app/screens/backupWalletSteps/index.tsx index 1b4b9bfb0..15547ef67 100644 --- a/src/app/screens/backupWalletSteps/index.tsx +++ b/src/app/screens/backupWalletSteps/index.tsx @@ -51,6 +51,9 @@ export default function BackupWalletSteps(): JSX.Element { navigate('/backup'); } })(); + return () => { + setSeedPhrase(''); + }; }, []); const handleSeedCheckContinue = () => { @@ -80,7 +83,7 @@ export default function BackupWalletSteps(): JSX.Element { const handleConfirmPasswordContinue = async () => { if (confirmPassword === password) { disableWalletExistsGuard?.(); - await createWallet(seedPhrase); + await createWallet(); // TODO move this somwhere else await changePassword('', password); navigate('/wallet-success/create', { replace: true }); } else { diff --git a/src/app/screens/createPassword/index.tsx b/src/app/screens/createPassword/index.tsx index 68596b79a..ebb577496 100644 --- a/src/app/screens/createPassword/index.tsx +++ b/src/app/screens/createPassword/index.tsx @@ -38,6 +38,7 @@ const StepDot = styled.div<{ marginRight: props.theme.spacing(4), })); +// TODO refactor to delete this whole screen and use the backup steps screen instead function CreatePassword(): JSX.Element { const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); @@ -48,7 +49,7 @@ function CreatePassword(): JSX.Element { const { t } = useTranslation('translation', { keyPrefix: 'CREATE_PASSWORD_SCREEN' }); const { createWallet } = useWalletReducer(); const { disableWalletExistsGuard } = useWalletExistsContext(); - const { getSeed, changePassword } = useSeedVault(); + const { changePassword } = useSeedVault(); const handleContinuePasswordCreation = () => { setCurrentStepIndex(1); @@ -59,8 +60,7 @@ function CreatePassword(): JSX.Element { try { setIsCreatingWallet(true); disableWalletExistsGuard?.(); - const seedPhrase = await getSeed(); - await createWallet(seedPhrase); + await createWallet(); // TODO move this somwhere else await changePassword('', password); navigate('/wallet-success/create', { replace: true }); } catch (err) { diff --git a/src/app/screens/landing/index.tsx b/src/app/screens/landing/index.tsx index 890837c8d..2b8473f63 100644 --- a/src/app/screens/landing/index.tsx +++ b/src/app/screens/landing/index.tsx @@ -223,40 +223,43 @@ function Landing() { }, ]; - const proceedToWallet = useCallback(async (isRestore?: boolean) => { - const isLegalAccepted = getIsTermsAccepted(); + const proceedToWallet = useCallback( + async (isRestore?: boolean) => { + const isLegalAccepted = getIsTermsAccepted(); + + if (isInOptions()) { + if (isLegalAccepted) { + if (isRestore) { + navigate(`/restoreWallet`); + } else { + navigate(`/backup`); + } + } else { + const params = isRestore ? '?restore=true' : ''; + navigate(`/legal${params}`); + } + return; + } - if (isInOptions()) { if (isLegalAccepted) { if (isRestore) { - navigate(`/restoreWallet`); + await chrome.tabs.create({ + url: chrome.runtime.getURL(`options.html#/restoreWallet`), + }); } else { - navigate(`/backup`); + await chrome.tabs.create({ + url: chrome.runtime.getURL(`options.html#/backup`), + }); } } else { const params = isRestore ? '?restore=true' : ''; - navigate(`/legal${params}`); - } - return; - } - - if (isLegalAccepted) { - if (isRestore) { await chrome.tabs.create({ - url: chrome.runtime.getURL(`options.html#/restoreWallet`), - }); - } else { - await chrome.tabs.create({ - url: chrome.runtime.getURL(`options.html#/backup`), + url: chrome.runtime.getURL(`options.html#/legal${params}`), }); } - } else { - const params = isRestore ? '?restore=true' : ''; - await chrome.tabs.create({ - url: chrome.runtime.getURL(`options.html#/legal${params}`), - }); - } - }, []); + }, + [navigate], + ); const renderLandingSection = () => ( <> From c16376306a4a0404f925eae0431dc15699ad068e Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Wed, 3 Apr 2024 09:46:05 +0000 Subject: [PATCH 17/18] release: v0.33.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ceae648a9..0738b68fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "xverse-web-extension", - "version": "0.33.0", + "version": "0.33.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "xverse-web-extension", - "version": "0.33.0", + "version": "0.33.1", "dependencies": { "@ledgerhq/hw-transport-webusb": "^6.27.13", "@phosphor-icons/react": "^2.0.10", diff --git a/package.json b/package.json index 0ccdb29a5..6b30d92b8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xverse-web-extension", "description": "A Bitcoin wallet for Web3", - "version": "0.33.0", + "version": "0.33.1", "private": true, "engines": { "node": "^18.18.2" From e66cc85068852d152e385bba78f0aac307ee4f07 Mon Sep 17 00:00:00 2001 From: fede erbes Date: Wed, 3 Apr 2024 12:41:44 +0200 Subject: [PATCH 18/18] chore: fix release.yml (#173) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 65894d566..b398ad9cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -88,7 +88,7 @@ jobs: asset_content_type: application/zip - id: push-to-public name: Push to public remote - if: ${{ contains(github.repositoryUrl, 'private' }} + if: ${{ contains(github.repositoryUrl, 'private') }} env: REMOTE_REPO: xverse-web-extension run: |