diff --git a/.env b/.env index 4c4b077..759d7a8 100644 --- a/.env +++ b/.env @@ -6,9 +6,9 @@ SMSCODE=1660 ZHB_ACCOUNT=18571458300 ZHB_PASSWORD=1 -# ZHB_BASE_URL="https://shengyibao.meiguanjia.net/shair/components/shair-web/base-system/index.html#" +ZHB_ADMIN_URL="https://shengyibao.meiguanjia.net/shair/components/shair-web/base-system/index.html#" ZHB_BASE_URL="https://shengyibao.meiguanjia.net/young/" - +ZHB_H5_URL="http://shengyibao.meiguanjia.net/h5/index.html#tenantId=1578151&view=0" MGJ_ACCOUNT=美管加演示 MGJ_PASSWORD=1 diff --git a/.gitignore b/.gitignore index b0435b6..4f045aa 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ node_modules/ /blob-report/ /playwright/.cache/ .auth/ +.images/ diff --git a/package-lock.json b/package-lock.json index 2060f26..1c49860 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,129 +1,748 @@ { - "name": "playwright-demo", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "playwright-demo", - "version": "1.0.0", - "license": "ISC", - "devDependencies": { - "@faker-js/faker": "^9.0.3", - "@playwright/test": "^1.48.1", - "@types/node": "^22.7.5", - "dotenv": "^16.4.5" - } - }, - "node_modules/@faker-js/faker": { - "version": "9.0.3", - "resolved": "https://registry.npmmirror.com/@faker-js/faker/-/faker-9.0.3.tgz", - "integrity": "sha512-lWrrK4QNlFSU+13PL9jMbMKLJYXDFu3tQfayBsMXX7KL/GiQeqfB1CzHkqD5UHBUtPAuPo6XwGbMFNdVMZObRA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/fakerjs" - } - ], - "license": "MIT", - "engines": { - "node": ">=18.0.0", - "npm": ">=9.0.0" - } - }, - "node_modules/@playwright/test": { - "version": "1.48.1", - "resolved": "https://registry.npmmirror.com/@playwright/test/-/test-1.48.1.tgz", - "integrity": "sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright": "1.48.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/playwright": { - "version": "1.48.1", - "resolved": "https://registry.npmmirror.com/playwright/-/playwright-1.48.1.tgz", - "integrity": "sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright-core": "1.48.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/playwright-core": { - "version": "1.48.1", - "resolved": "https://registry.npmmirror.com/playwright-core/-/playwright-core-1.48.1.tgz", - "integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "license": "MIT" - } - } + "name": "playwright-demo", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "playwright-demo", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "sharp": "^0.33.5", + "tesseract.js": "^5.1.1" + }, + "devDependencies": { + "@faker-js/faker": "^9.0.3", + "@playwright/test": "^1.48.1", + "@types/node": "^22.7.5", + "dotenv": "^16.4.5" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@faker-js/faker": { + "version": "9.0.3", + "resolved": "https://registry.npmmirror.com/@faker-js/faker/-/faker-9.0.3.tgz", + "integrity": "sha512-lWrrK4QNlFSU+13PL9jMbMKLJYXDFu3tQfayBsMXX7KL/GiQeqfB1CzHkqD5UHBUtPAuPo6XwGbMFNdVMZObRA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/fakerjs" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.0.0", + "npm": ">=9.0.0" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@playwright/test": { + "version": "1.48.1", + "resolved": "https://registry.npmmirror.com/@playwright/test/-/test-1.48.1.tgz", + "integrity": "sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.48.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/idb-keyval": { + "version": "6.2.1", + "resolved": "https://registry.npmmirror.com/idb-keyval/-/idb-keyval-6.2.1.tgz", + "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==", + "license": "Apache-2.0" + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/is-electron": { + "version": "2.2.2", + "resolved": "https://registry.npmmirror.com/is-electron/-/is-electron-2.2.2.tgz", + "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==", + "license": "MIT" + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "license": "MIT", + "bin": { + "opencollective-postinstall": "index.js" + } + }, + "node_modules/playwright": { + "version": "1.48.1", + "resolved": "https://registry.npmmirror.com/playwright/-/playwright-1.48.1.tgz", + "integrity": "sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.48.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.48.1", + "resolved": "https://registry.npmmirror.com/playwright-core/-/playwright-core-1.48.1.tgz", + "integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmmirror.com/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/tesseract.js": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/tesseract.js/-/tesseract.js-5.1.1.tgz", + "integrity": "sha512-lzVl/Ar3P3zhpUT31NjqeCo1f+D5+YfpZ5J62eo2S14QNVOmHBTtbchHm/YAbOOOzCegFnKf4B3Qih9LuldcYQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "bmp-js": "^0.1.0", + "idb-keyval": "^6.2.0", + "is-electron": "^2.2.2", + "is-url": "^1.2.4", + "node-fetch": "^2.6.9", + "opencollective-postinstall": "^2.0.3", + "regenerator-runtime": "^0.13.3", + "tesseract.js-core": "^5.1.1", + "wasm-feature-detect": "^1.2.11", + "zlibjs": "^0.3.1" + } + }, + "node_modules/tesseract.js-core": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/tesseract.js-core/-/tesseract.js-core-5.1.1.tgz", + "integrity": "sha512-KX3bYSU5iGcO1XJa+QGPbi+Zjo2qq6eBhNjSGR5E5q0JtzkoipJKOUQD7ph8kFyteCEfEQ0maWLu8MCXtvX5uQ==", + "license": "Apache-2.0" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "license": "0BSD", + "optional": true + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/wasm-feature-detect": { + "version": "1.8.0", + "resolved": "https://registry.npmmirror.com/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz", + "integrity": "sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==", + "license": "Apache-2.0" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/zlibjs": { + "version": "0.3.1", + "resolved": "https://registry.npmmirror.com/zlibjs/-/zlibjs-0.3.1.tgz", + "integrity": "sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==", + "license": "MIT", + "engines": { + "node": "*" + } + } + } } diff --git a/package.json b/package.json index 87794bc..2f02122 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,9 @@ "@playwright/test": "^1.48.1", "@types/node": "^22.7.5", "dotenv": "^16.4.5" + }, + "dependencies": { + "sharp": "^0.33.5", + "tesseract.js": "^5.1.1" } } diff --git a/playwright.config.js b/playwright.config.js index 99e912c..5d05fc1 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -6,7 +6,6 @@ const path = require('path'); // Read from ".env" file. dotenv.config({ path: path.resolve(__dirname, '.env') }); const hlkAuthFile = path.join(__dirname, '.auth/hlk_admin.json'); -const zhbAuthFile = path.join(__dirname, '.auth/zhb_admin.json'); const mgjAuthFile = path.join(__dirname, '.auth/mgj_admin.json'); /** @@ -66,7 +65,6 @@ module.exports = defineConfig({ use: { baseURL: process.env.ZHB_BASE_URL, ...devices['Desktop Chrome'], - storageState: zhbAuthFile, }, testMatch: '**/tests/zhb/**.spec.js', dependencies: ['zhb_setup'], diff --git a/tests/hlk/demo.spec.js b/tests/hlk/demo.spec.js index 89e6595..6b6d6a2 100644 --- a/tests/hlk/demo.spec.js +++ b/tests/hlk/demo.spec.js @@ -1,5 +1,5 @@ const { test, expect } = require('./fixtures/common'); -const { Customer } = require('./pom/hlk/customer'); +const { Customer } = require('./pom/customer'); const { faker } = require('@faker-js/faker/locale/zh_CN'); for (let i = 0; i < 10; i++) { diff --git a/tests/hlk/fixtures/h5Fixture.js b/tests/hlk/fixtures/h5Fixture.js index 1e504ee..f378207 100644 --- a/tests/hlk/fixtures/h5Fixture.js +++ b/tests/hlk/fixtures/h5Fixture.js @@ -1,5 +1,5 @@ const { test: base, expect } = require('./base'); -const { H5LoginPage } = require('../pom/hlk/h5LoginPage'); +const { H5LoginPage } = require('../pom/h5LoginPage'); const test = base.extend({ /** diff --git a/tests/hlk/fixtures/touchFixture.js b/tests/hlk/fixtures/touchFixture.js index 78da9e1..fe1fa97 100644 --- a/tests/hlk/fixtures/touchFixture.js +++ b/tests/hlk/fixtures/touchFixture.js @@ -1,5 +1,5 @@ const { test: base, expect } = require('./base'); -const { CustomerPage } = require('../pom/hlk/customerPage'); +const { CustomerPage } = require('../pom/customerPage'); const test = base.extend({ /** diff --git a/tests/hlk/pom/hlk/customer.js b/tests/hlk/pom/customer.js similarity index 100% rename from tests/hlk/pom/hlk/customer.js rename to tests/hlk/pom/customer.js diff --git a/tests/hlk/pom/hlk/customerPage.js b/tests/hlk/pom/customerPage.js similarity index 100% rename from tests/hlk/pom/hlk/customerPage.js rename to tests/hlk/pom/customerPage.js diff --git a/tests/hlk/pom/hlk/h5LoginPage.js b/tests/hlk/pom/h5LoginPage.js similarity index 100% rename from tests/hlk/pom/hlk/h5LoginPage.js rename to tests/hlk/pom/h5LoginPage.js diff --git a/tests/hlk/pom/hlk/homeNavigationPage.js b/tests/hlk/pom/homeNavigationPage.js similarity index 100% rename from tests/hlk/pom/hlk/homeNavigationPage.js rename to tests/hlk/pom/homeNavigationPage.js diff --git a/tests/hlk/pom/hlk/touchCustomerPage.js b/tests/hlk/pom/touchCustomerPage.js similarity index 100% rename from tests/hlk/pom/hlk/touchCustomerPage.js rename to tests/hlk/pom/touchCustomerPage.js diff --git a/tests/hlk/pom/hlk/touchLoginPage.js b/tests/hlk/pom/touchLoginPage.js similarity index 100% rename from tests/hlk/pom/hlk/touchLoginPage.js rename to tests/hlk/pom/touchLoginPage.js diff --git a/tests/mgj/fixture/h5Fixture.js b/tests/mgj/fixture/h5Fixture.js new file mode 100644 index 0000000..1e504ee --- /dev/null +++ b/tests/mgj/fixture/h5Fixture.js @@ -0,0 +1,14 @@ +const { test: base, expect } = require('./base'); +const { H5LoginPage } = require('../pom/hlk/h5LoginPage'); + +const test = base.extend({ + /** + * @type {H5LoginPage} + */ + h5LoginPage: async ({ h5Page }, use) => { + const h5LoginPage = new H5LoginPage(h5Page); + await use(h5LoginPage); + }, +}); + +module.exports = { test, expect }; diff --git a/tests/mgj/pom/h5LoginPage.js b/tests/mgj/pom/h5LoginPage.js new file mode 100644 index 0000000..f7d1483 --- /dev/null +++ b/tests/mgj/pom/h5LoginPage.js @@ -0,0 +1,19 @@ +class H5LoginPage { + constructor(page) { + this.page = page; + this.$account = this.page.locator('.input', { hasText: '请输入手机号码' }).locator('input'); + this.$SMSCode = this.page.locator('.input', { hasText: '请输入验证码' }).locator('input'); + this.$loginBtn = this.page.locator('uni-button').filter({ hasText: /^登录$/ }); + } + + login = async (account) => { + await this.page.locator('.login_btn').click(); + await this.$account.click(); + await this.$account.fill(account); + await this.$SMSCode.fill(process.env.SMSCODE); + await this.page.getByText('同意隐私协议').click(); + await this.$loginBtn.click(); + }; +} + +module.exports = { H5LoginPage }; diff --git a/tests/setup/zhb.setup.js b/tests/setup/zhb.setup.js index 1ca126b..82deda5 100644 --- a/tests/setup/zhb.setup.js +++ b/tests/setup/zhb.setup.js @@ -1,6 +1,7 @@ const { test: setup, expect } = require('@playwright/test'); const path = require('path'); -const zhbAuthFile = path.join(__dirname, '../../.auth/zhb_admin.json'); +const zhbAuthFile = '.auth/zhb.json'; +const zhbAdminAuthFile = '.auth/zhb_admin.json'; setup('zhb总部管理员登录', async ({ page, baseURL }) => { const account = process.env.ZHB_ACCOUNT; @@ -18,3 +19,22 @@ setup('zhb总部管理员登录', async ({ page, baseURL }) => { await expect(page.locator('#tab_main li').filter({ hasText: '营业' })).toBeVisible(); await page.context().storageState({ path: zhbAuthFile }); }); + +// setup('zhb管理页面登录', async ({ page }) => { +// const account = process.env.ZHB_ACCOUNT; +// const password = process.env.ZHB_PASSWORD; +// const baseURL = process.env.ZHB_ADMIN_URL; + +// await page.goto(baseURL); + +// await page.getByPlaceholder('账户').fill(account); +// await page.getByPlaceholder('密码').fill(password); +// await page.getByRole('button', { name: '登 录' }).click(); +// await expect(page.locator('a').filter({ hasText: /^收银$/ })).toBeVisible(); +// await page +// .locator('a') +// .filter({ hasText: /^顾客$/ }) +// .click(); +// await expect(page.getByText('顾客概要分析')).toBeVisible(); +// await page.context().storageState({ path: zhbAdminAuthFile }); +// }); diff --git a/tests/utils/helper.js b/tests/utils/helper.js new file mode 100644 index 0000000..2ee861f --- /dev/null +++ b/tests/utils/helper.js @@ -0,0 +1,42 @@ +const sharp = require('sharp'); +const Tesseract = require('tesseract.js'); +const path = require('path'); + +/** + * 处理图像并进行验证码识别 + * @param {string} inputImageName - 输入图像文件名(位于 .images 文件夹内) + * @param {string} outputImageName - 输出处理后图像的文件名(位于 .images 文件夹内) + * @returns {Promise} - 返回识别的文本结果 + */ +async function processAndRecognizeCaptcha(inputImagePath, outputImagePath) { + try { + // 图像处理 + await sharp(inputImagePath) + // .sharpen() + .modulate({ + brightness: 1.2, // 增加亮度 + contrast: 1.5, // 增强对比度 + }) + .resize(800) // 调整图像宽度为800像素,保持纵横比 + .grayscale() // 转换为灰度图 + .threshold(128) // 二值化,阈值设定为128 + .toFile(outputImagePath); + + console.log('图像处理完成:', outputImagePath); + + // 图像识别 + const { + data: { text }, + } = await Tesseract.recognize(outputImagePath, 'eng', { + langPath: './tessdata', + }); + + console.log('识别结果:', text.trim()); + return text.replace(/\s+/g, '').trim(); // 返回识别的文本结果 + } catch (err) { + console.error('处理或识别出错:', err); + throw err; // 将错误抛出以供调用者处理 + } +} + +module.exports = { processAndRecognizeCaptcha }; diff --git a/tests/zhb/demo.spec.js b/tests/zhb/demo.spec.js index e432660..8984926 100644 --- a/tests/zhb/demo.spec.js +++ b/tests/zhb/demo.spec.js @@ -7,9 +7,11 @@ test('demo', async ({ zhbPage, customerPage }) => { .filter({ has: zhbPage.locator('.area-name', { hasText: '二楼' }) }); const $$room = $area.locator('.room-list .room'); - await zhbPage.locator('#tab_main li').filter({ hasText: '顾客' }).click(); const customer = new Customer(); - await customerPage.createCustomer(customer); + await test.step('创建顾客', async () => { + await zhbPage.locator('#tab_main li').filter({ hasText: '顾客' }).click(); + await customerPage.createCustomer(customer); + }); let useRoomName; await test.step('购买商品', async () => { @@ -95,3 +97,97 @@ test('demo', async ({ zhbPage, customerPage }) => { await expect($cleanRoom).toContainText('空房'); }); }); + +test('h5 demo', async ({ + zhbAdminPage, + // zhbPage, + h5Page, + h5LoginPage, + // customerPage +}) => { + // const customer = new Customer(); + // await test.step('创建顾客', async () => { + // await zhbPage.locator('#tab_main li').filter({ hasText: '顾客' }).click(); + // await customerPage.createCustomer(customer); + // }); + + // await test.step('搜索顾客进行开卡', async () => { + // await zhbPage.getByRole('textbox', { name: '输入会员手机号或姓名搜索' }).fill(customer.phone); + // await zhbPage.locator('#page_member svg').click(); + // await zhbPage + // .locator('.searchresultBox tbody tr') + // .first() + // .locator('#page_member') + // .getByText('详情') + // .click(); + // await expect(zhbPage.getByText('会员卡 点击卡片即可用卡进行结算哦~')).toBeVisible(); + // await zhbPage + // .locator('p') + // .filter({ hasText: '会员卡 点击卡片即可用卡进行结算哦~' }) + // .locator('span') + // .nth(2) + // .click(); + // await zhbPage.locator('#page_memberCard').getByText('5000元储值卡', { exact: true }).click(); + + // await expect(zhbPage.locator('#page_memberCard .cashierBox tbody tr').first()).toBeVisible(); + // await zhbPage + // .locator('#page_memberCard') + // .getByText(/结\s算/) + // .click(); + + // await expect(async () => { + // const $signature = zhbPage.locator('#page_pay').getByText('结算签字'); + // await $signature.click(); + // await expect($signature).not.toHaveClass(/checked/, { timeout: 2000 }); + // }).toPass(); + + // await expect(async () => { + // const $cashBtn = zhbPage.locator('#page_pay .pay_cash'); + // await $cashBtn.click(); + // await expect(zhbPage.locator('#page_pay .pay_cash.selected')).toBeVisible(); + // await zhbPage + // .locator('#page_pay span') + // .filter({ hasText: /结\s算/ }) + // .click(); + // await expect(zhbPage.locator('#payConfirm').getByText('立即返回')).not.toBeVisible({ + // timeout: 2000, + // }); + // }).toPass(); + // }); + + const $smsCodeInput = h5Page.getByRole('textbox', { name: '验证码', exact: true }); + await test.step('获取手机验证码', async () => { + const graphCode = await h5LoginPage.sendSmsCode('17770898274'); + await h5Page.getByRole('textbox', { name: '请输入图形验证码' }).fill(graphCode); + await h5Page.locator('#setup_loginForm').getByText('获取验证码').nth(1).first().tap(); + await expect(h5Page.getByText('重新发送')).toBeVisible(); + }); + + let smsCode; + await test.step('获取短信验证码', async () => { + await zhbAdminPage + .locator('a') + .filter({ hasText: /^管理$/ }) + .click(); + await zhbAdminPage.locator('.menu-item').getByText('短信发送记录', { exact: true }).click(); + const $smsCodeTr = zhbAdminPage + .locator('#routerView iframe') + .contentFrame() + .locator('.table-responsive tbody tr') + .filter({ hasText: '17770898274' }) + .first() + .locator('td') + .nth(2); + await expect($smsCodeTr).toBeVisible(); + const text = await $smsCodeTr.innerText(); + smsCode = text.match(/验证码是(\d{4})/)[1]; + }); + expect(smsCode).not.toBeUndefined(); + + await test.step('使用短信验证码登录h5', async () => { + await h5Page.getByRole('textbox', { name: '验证码', exact: true }).fill(smsCode); + await h5Page.locator('#setup_loginForm span').first().tap(); + await h5Page.getByText('绑定', { exact: true }).tap(); + await h5Page.waitForTimeout(5000); + }); +}); diff --git a/tests/zhb/fixture/base.js b/tests/zhb/fixture/base.js index 4fa77ba..231b324 100644 --- a/tests/zhb/fixture/base.js +++ b/tests/zhb/fixture/base.js @@ -1,12 +1,13 @@ -const { test: base, expect } = require('@playwright/test'); -const authFile = '.auth/zhb_admin.json'; +const { test: base, expect, devices } = require('@playwright/test'); +const zhbAuthFile = '.auth/zhb.json'; +const zhbAdminAuthFile = '.auth/zhb_admin.json'; const test = base.extend({ /** * @type {import('@playwright/test').Page} */ zhbPage: async ({ browser, baseURL }, use) => { const context = await browser.newContext({ - storageState: authFile, + storageState: zhbAuthFile, }); const page = await context.newPage(); await page.goto(baseURL); @@ -17,6 +18,47 @@ const test = base.extend({ await page.close(); await context.close(); }, + /** + * @type {import('@playwright/test').Page} + */ + zhbAdminPage: async ({ browser }, use) => { + const baseURL = process.env.ZHB_ADMIN_URL; + const account = process.env.ZHB_ACCOUNT; + const password = process.env.ZHB_PASSWORD; + const context = await browser.newContext({ + storageState: zhbAdminAuthFile, + }); + const page = await context.newPage(); + await page.goto(baseURL); + console.log(baseURL); + + await page.getByPlaceholder('账户').fill(account); + await page.getByPlaceholder('密码').fill(password); + await page.getByRole('button', { name: '登 录' }).click(); + await expect(page.locator('a').filter({ hasText: /^收银$/ })).toBeVisible(); + + await use(page); + + await page.close(); + await context.close(); + }, + /** + * @type {import('@playwright/test').Page} + */ + h5Page: async ({ browser }, use) => { + const baseURL = process.env.ZHB_H5_URL; + const iPhone = devices['iPhone 14']; + const context = await browser.newContext({ + ...iPhone, + storageState: undefined, + hasTouch: true, + isMobile: true, // 设置为移动设备 + viewport: iPhone.viewport, // 使用 iPhone 的视口配置 + }); + const page = await context.newPage(); + await page.goto(baseURL); + await use(page); + }, }); module.exports = { diff --git a/tests/zhb/fixture/common.js b/tests/zhb/fixture/common.js index 752350b..282dd0b 100644 --- a/tests/zhb/fixture/common.js +++ b/tests/zhb/fixture/common.js @@ -1,6 +1,8 @@ const { mergeTests } = require('@playwright/test'); +const { test: baseTest } = require('./base'); +const { test: h5LoginTest } = require('./h5Fixture'); const { test: customerTest } = require('./customerFixture'); -export const test = mergeTests(customerTest); +export const test = mergeTests(baseTest, customerTest, h5LoginTest); export { expect } from '@playwright/test'; diff --git a/tests/zhb/fixture/h5Fixture.js b/tests/zhb/fixture/h5Fixture.js new file mode 100644 index 0000000..f378207 --- /dev/null +++ b/tests/zhb/fixture/h5Fixture.js @@ -0,0 +1,14 @@ +const { test: base, expect } = require('./base'); +const { H5LoginPage } = require('../pom/h5LoginPage'); + +const test = base.extend({ + /** + * @type {H5LoginPage} + */ + h5LoginPage: async ({ h5Page }, use) => { + const h5LoginPage = new H5LoginPage(h5Page); + await use(h5LoginPage); + }, +}); + +module.exports = { test, expect }; diff --git a/tests/zhb/pom/customerPage.js b/tests/zhb/pom/customerPage.js index 5dc0b50..c3174bb 100644 --- a/tests/zhb/pom/customerPage.js +++ b/tests/zhb/pom/customerPage.js @@ -4,7 +4,7 @@ const { expect } = require('@playwright/test'); export class Customer { constructor({ name = faker.person.fullName(), - phone = faker.helpers.fromRegExp(/1[3-9][0-9]{6}/), + phone = faker.helpers.fromRegExp(/123[0-1]{8}/), } = {}) { this.name = name; this.phone = phone; diff --git a/tests/zhb/pom/h5LoginPage.js b/tests/zhb/pom/h5LoginPage.js new file mode 100644 index 0000000..d2de043 --- /dev/null +++ b/tests/zhb/pom/h5LoginPage.js @@ -0,0 +1,25 @@ +const { processAndRecognizeCaptcha } = require('../../utils/helper'); + +class H5LoginPage { + constructor(page) { + this.page = page; + this.$account = this.page.getByPlaceholder('此处请输入手机号'); + this.$GraphCode = this.page.getByRole('textbox', { name: '请输入图形验证码' }); + this.$SmsCode = this.page.getByRole('textbox', { name: '验证码', exact: true }); + this.$loginBtn = this.page.locator('uni-button').filter({ hasText: /^登录$/ }); + } + + sendSmsCode = async (account) => { + const imagePath = '.images/captcha.png'; + const outputImagePath = '.images/output-captcha.png'; + + await this.$account.fill(account); + const $graph = this.page.getByRole('img', { name: '图形验证码' }); + await $graph.waitFor(); + await $graph.screenshot({ path: imagePath }); + + return await processAndRecognizeCaptcha(imagePath, outputImagePath); + }; +} + +module.exports = { H5LoginPage };