chore: first commit
This commit is contained in:
41
.github/workflows/monocart.yml
vendored
Normal file
41
.github/workflows/monocart.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: Monocart Report
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: npx playwright install --with-deps firefox
|
||||
|
||||
- name: Run tests
|
||||
run: npx playwright test tests/api-command.spec.ts --project=firefox
|
||||
continue-on-error: true
|
||||
|
||||
- name: Deploy report to GitHub Pages
|
||||
if: always()
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_branch: gh-pages
|
||||
publish_dir: monocart-report
|
||||
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
# Playwright
|
||||
node_modules/
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
/playwright/.auth/
|
||||
277
data.json
Normal file
277
data.json
Normal file
@@ -0,0 +1,277 @@
|
||||
[
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "L",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "LV",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "L",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "MS",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "L",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "BT",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "L",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "WIC",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "BL",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "Open" },
|
||||
"roomName": "LV",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "BL",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "Open" },
|
||||
"roomName": "MS",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "BL",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "Open" },
|
||||
"roomName": "JB",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "KN",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "A",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "KN",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "LV",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "A",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "LV",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "BR1",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "A",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "BR1",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "BR2",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "A",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "BR2",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "MS",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "A",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "MS",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "MR",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "AC",
|
||||
"deviceType": "A",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "MR",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "FT1",
|
||||
"deviceType": "A",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "LV",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "FT2",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "LV",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "PM25",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "LV",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "DL",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "KN",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "KC",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "KN",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
},
|
||||
{
|
||||
"commandType": "C",
|
||||
"deviceName": "ERV",
|
||||
"deviceType": "S",
|
||||
"floorName": "L3",
|
||||
"merchantName": "SAVY",
|
||||
"payload": { "action": "On" },
|
||||
"roomName": "LV",
|
||||
"towerNumber": "T2",
|
||||
"unitNumber": "01"
|
||||
}
|
||||
]
|
||||
BIN
monocart-report.zip
Normal file
BIN
monocart-report.zip
Normal file
Binary file not shown.
52
monocart-report/index.html
Normal file
52
monocart-report/index.html
Normal file
File diff suppressed because one or more lines are too long
1
monocart-report/index.json
Normal file
1
monocart-report/index.json
Normal file
File diff suppressed because one or more lines are too long
861
package-lock.json
generated
Normal file
861
package-lock.json
generated
Normal file
@@ -0,0 +1,861 @@
|
||||
{
|
||||
"name": "playwright",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "playwright",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.57.0",
|
||||
"@types/node": "^25.0.3",
|
||||
"monocart-reporter": "^2.9.23"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.57.0",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.57.0.tgz",
|
||||
"integrity": "sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.57.0"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "25.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz",
|
||||
"integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.34",
|
||||
"negotiator": "0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts/node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts/node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-loose": {
|
||||
"version": "8.5.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.5.2.tgz",
|
||||
"integrity": "sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.15.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.4",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "14.0.2",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz",
|
||||
"integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/console-grid": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/console-grid/-/console-grid-2.2.3.tgz",
|
||||
"integrity": "sha512-+mecFacaFxGl+1G31IsCx41taUXuW2FxX+4xIE0TIPhgML+Jb9JFcBWGhhWerd1/vhScubdmHqTwOhB0KCUUAg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "5.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/content-type": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookies": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz",
|
||||
"integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "~2.0.0",
|
||||
"keygrip": "~1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
|
||||
"integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/destroy": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8",
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/eight-colors": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.1.tgz",
|
||||
"integrity": "sha512-7nXPYDeKh6DgJDR/mpt2G7N/hCNSGwwoPVmoI3+4TEwOb07VFN1WMPG0DFf6nMEjrkgdj8Og7l7IaEEk3VE6Zg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.6",
|
||||
"signal-exit": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"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,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/html-escaper": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
|
||||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/http-assert": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz",
|
||||
"integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"deep-equal": "~1.0.1",
|
||||
"http-errors": "~1.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/http-assert/node_modules/depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/http-assert/node_modules/http-errors": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
|
||||
"integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.4",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/http-assert/node_modules/statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "~2.0.0",
|
||||
"inherits": "~2.0.4",
|
||||
"setprototypeof": "~1.2.0",
|
||||
"statuses": "~2.0.2",
|
||||
"toidentifier": "~1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/istanbul-lib-coverage": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
|
||||
"integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/istanbul-lib-report": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
|
||||
"integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"istanbul-lib-coverage": "^3.0.0",
|
||||
"make-dir": "^4.0.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/istanbul-reports": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
|
||||
"integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"html-escaper": "^2.0.0",
|
||||
"istanbul-lib-report": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/keygrip": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
|
||||
"integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
|
||||
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tsscmp": "1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/koa": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/koa/-/koa-3.1.1.tgz",
|
||||
"integrity": "sha512-KDDuvpfqSK0ZKEO2gCPedNjl5wYpfj+HNiuVRlbhd1A88S3M0ySkdf2V/EJ4NWt5dwh5PXCdcenrKK2IQJAxsg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "^1.3.8",
|
||||
"content-disposition": "~0.5.4",
|
||||
"content-type": "^1.0.5",
|
||||
"cookies": "~0.9.1",
|
||||
"delegates": "^1.0.0",
|
||||
"destroy": "^1.2.0",
|
||||
"encodeurl": "^2.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"fresh": "~0.5.2",
|
||||
"http-assert": "^1.5.0",
|
||||
"http-errors": "^2.0.0",
|
||||
"koa-compose": "^4.1.0",
|
||||
"mime-types": "^3.0.1",
|
||||
"on-finished": "^2.4.1",
|
||||
"parseurl": "^1.3.3",
|
||||
"statuses": "^2.0.1",
|
||||
"type-is": "^2.0.1",
|
||||
"vary": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/koa-compose": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz",
|
||||
"integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/koa-static-resolver": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/koa-static-resolver/-/koa-static-resolver-1.0.6.tgz",
|
||||
"integrity": "sha512-ZX5RshSzH8nFn05/vUNQzqw32nEigsPa67AVUr6ZuQxuGdnCcTLcdgr4C81+YbJjpgqKHfacMBd7NmJIbj7fXw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lz-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lz-utils/-/lz-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-CMkfimAypidTtWjNDxY8a1bc1mJdyEh04V2FfEQ5Zh8Nx4v7k850EYa+dOWGn9hKG5xOyHP5MkuduAZCTHRvJw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
|
||||
"integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^7.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
||||
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.54.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
|
||||
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
|
||||
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "^1.54.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/monocart-coverage-reports": {
|
||||
"version": "2.12.9",
|
||||
"resolved": "https://registry.npmjs.org/monocart-coverage-reports/-/monocart-coverage-reports-2.12.9.tgz",
|
||||
"integrity": "sha512-vtFqbC3Egl4nVa1FSIrQvMPO6HZtb9lo+3IW7/crdvrLNW2IH8lUsxaK0TsKNmMO2mhFWwqQywLV2CZelqPgwA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.15.0",
|
||||
"acorn-loose": "^8.5.2",
|
||||
"acorn-walk": "^8.3.4",
|
||||
"commander": "^14.0.0",
|
||||
"console-grid": "^2.2.3",
|
||||
"eight-colors": "^1.3.1",
|
||||
"foreground-child": "^3.3.1",
|
||||
"istanbul-lib-coverage": "^3.2.2",
|
||||
"istanbul-lib-report": "^3.0.1",
|
||||
"istanbul-reports": "^3.2.0",
|
||||
"lz-utils": "^2.1.0",
|
||||
"monocart-locator": "^1.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"mcr": "lib/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/monocart-locator": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/monocart-locator/-/monocart-locator-1.0.2.tgz",
|
||||
"integrity": "sha512-v8W5hJLcWMIxLCcSi/MHh+VeefI+ycFmGz23Froer9QzWjrbg4J3gFJBuI/T1VLNoYxF47bVPPxq8ZlNX4gVCw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/monocart-reporter": {
|
||||
"version": "2.9.23",
|
||||
"resolved": "https://registry.npmjs.org/monocart-reporter/-/monocart-reporter-2.9.23.tgz",
|
||||
"integrity": "sha512-FSz8908/2FIBJRMD9OdoVXcg7ndGmgiB3GmK2tojeMMrp5OSDt02ksv88GehlLRRzoL2jjf8fuSIHhi8u3QFxw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"console-grid": "^2.2.3",
|
||||
"eight-colors": "^1.3.1",
|
||||
"koa": "^3.0.1",
|
||||
"koa-static-resolver": "^1.0.6",
|
||||
"lz-utils": "^2.1.0",
|
||||
"monocart-coverage-reports": "^2.12.9",
|
||||
"monocart-locator": "^1.0.2",
|
||||
"nodemailer": "^7.0.6"
|
||||
},
|
||||
"bin": {
|
||||
"monocart": "lib/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/nodemailer": {
|
||||
"version": "7.0.12",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.12.tgz",
|
||||
"integrity": "sha512-H+rnK5bX2Pi/6ms3sN4/jRQvYSMltV6vqup/0SFOrxYYY/qoNvhXPlYq3e+Pm9RFJRwrMGbMIwi81M4dxpomhA==",
|
||||
"dev": true,
|
||||
"license": "MIT-0",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/on-finished": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ee-first": "1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.57.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.57.0.tgz",
|
||||
"integrity": "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.57.0"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.57.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.57.0.tgz",
|
||||
"integrity": "sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/statuses": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/tsscmp": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
|
||||
"integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6.x"
|
||||
}
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"content-type": "^1.0.5",
|
||||
"media-typer": "^1.1.0",
|
||||
"mime-types": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
||||
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"node-which": "bin/node-which"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
package.json
Normal file
17
package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "playwright",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "npx playwright test",
|
||||
"report": "npx monocart show-report monocart-report/index.html"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.57.0",
|
||||
"@types/node": "^25.0.3",
|
||||
"monocart-reporter": "^2.9.23"
|
||||
}
|
||||
}
|
||||
85
playwright.config.ts
Normal file
85
playwright.config.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { defineConfig, devices } from '@playwright/test'
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// import dotenv from 'dotenv';
|
||||
// import path from 'path';
|
||||
// dotenv.config({ path: path.resolve(__dirname, '.env') });
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: './tests',
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: [
|
||||
['html'],
|
||||
['monocart-reporter', {
|
||||
name: "Savy API Test Report",
|
||||
outputFile: './monocart-report/index.html'
|
||||
}]
|
||||
],
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('')`. */
|
||||
// baseURL: 'http://localhost:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: 'Tower-2_Floor-3_Unit-A',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'firefox',
|
||||
use: { ...devices['Desktop Firefox'] },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'webkit',
|
||||
use: { ...devices['Desktop Safari'] },
|
||||
},
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
// name: 'Mobile Chrome',
|
||||
// use: { ...devices['Pixel 5'] },
|
||||
// },
|
||||
// {
|
||||
// name: 'Mobile Safari',
|
||||
// use: { ...devices['iPhone 12'] },
|
||||
// },
|
||||
|
||||
/* Test against branded browsers. */
|
||||
// {
|
||||
// name: 'Microsoft Edge',
|
||||
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
||||
// },
|
||||
// {
|
||||
// name: 'Google Chrome',
|
||||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
||||
// },
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
// webServer: {
|
||||
// command: 'npm run start',
|
||||
// url: 'http://localhost:3000',
|
||||
// reuseExistingServer: !process.env.CI,
|
||||
// },
|
||||
})
|
||||
85
tepineo:tepi-dev/test-case/index.html
Normal file
85
tepineo:tepi-dev/test-case/index.html
Normal file
File diff suppressed because one or more lines are too long
217
tests/api-command.spec.ts
Normal file
217
tests/api-command.spec.ts
Normal file
@@ -0,0 +1,217 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import topics from '../topic.json'
|
||||
import crypto from 'crypto'
|
||||
|
||||
// Configuration
|
||||
const API_URL = 'https://api-dev.vegacloud.id'
|
||||
const API_COMMAND_PATH = '/device/v1/command'
|
||||
const API_STATUS_PATH = '/device/v1/status'
|
||||
const API_KEY = 'ak_sdbx:N8Xbvb4OYprJ-Mtw4QO6xw'
|
||||
const SECRET_KEY = 'sk_sdbx:zyJteO7W3szL41fWWB8WZEmKpp8KyJzi-9o9OovbpT4'
|
||||
|
||||
// Convert "01" -> "A", "02" -> "B", etc.
|
||||
function numToAlpha(numStr: string): string {
|
||||
const num = parseInt(numStr, 10)
|
||||
if (isNaN(num)) return numStr
|
||||
return String.fromCharCode(64 + num)
|
||||
}
|
||||
|
||||
// Helper function to sort keys deeply
|
||||
function sortKeysDeep(obj: any): any {
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(sortKeysDeep)
|
||||
}
|
||||
if (obj !== null && typeof obj === 'object') {
|
||||
return Object.keys(obj)
|
||||
.sort()
|
||||
.reduce((acc: any, key) => {
|
||||
acc[key] = sortKeysDeep(obj[key])
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
// Generate signature for POST request
|
||||
function generateSignatureForPost(body: any): { timestamp: number; nonce: string; signature: string } {
|
||||
const timestamp = Math.floor(Date.now() / 1000)
|
||||
const nonce = crypto.randomUUID()
|
||||
const sortedBody = sortKeysDeep(body)
|
||||
const jsonBody = JSON.stringify({
|
||||
timestamp,
|
||||
nonce,
|
||||
body: JSON.stringify(sortedBody)
|
||||
})
|
||||
|
||||
const signature = crypto
|
||||
.createHmac('sha256', SECRET_KEY)
|
||||
.update(jsonBody)
|
||||
.digest('hex')
|
||||
|
||||
return { timestamp, nonce, signature }
|
||||
}
|
||||
|
||||
// Parse query params from URL manually (matching Postman logic)
|
||||
function parseQueryParamsManual(url: string): Record<string, string> {
|
||||
const resultObject: Record<string, string> = {}
|
||||
const queryStartIndex = url.indexOf('?')
|
||||
|
||||
if (queryStartIndex === -1 || queryStartIndex === url.length - 1) {
|
||||
return resultObject
|
||||
}
|
||||
|
||||
const queryString = url.substring(queryStartIndex + 1)
|
||||
const pairs = queryString.split('&')
|
||||
|
||||
for (let i = 0; i < pairs.length; i++) {
|
||||
const pair = pairs[i]
|
||||
const parts = pair.split('=')
|
||||
|
||||
if (parts.length === 2) {
|
||||
const key = decodeURIComponent(parts[0].replace(/\+/g, ' '))
|
||||
const value = decodeURIComponent(parts[1].replace(/\+/g, ' '))
|
||||
resultObject[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return resultObject
|
||||
}
|
||||
|
||||
// Generate signature for GET request
|
||||
function generateSignatureForGet(url: string): { timestamp: number; nonce: string; signature: string } {
|
||||
const timestamp = Math.floor(Date.now() / 1000)
|
||||
const nonce = crypto.randomUUID()
|
||||
|
||||
const params = parseQueryParamsManual(url)
|
||||
const sortedParams = Object.keys(params)
|
||||
.sort()
|
||||
.reduce((acc: any, key) => {
|
||||
acc[key] = params[key]
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const jsonBody = JSON.stringify({
|
||||
timestamp,
|
||||
nonce,
|
||||
body: JSON.stringify(sortedParams)
|
||||
})
|
||||
|
||||
const signature = crypto
|
||||
.createHmac('sha256', SECRET_KEY)
|
||||
.update(jsonBody)
|
||||
.digest('hex')
|
||||
|
||||
return { timestamp, nonce, signature }
|
||||
}
|
||||
|
||||
test.describe('Device Command & Status Tests', () => {
|
||||
|
||||
const getPayload = (deviceName: string) => {
|
||||
if (deviceName === 'AC') return 'On'
|
||||
if (deviceName === 'BL') return 'Open'
|
||||
if (deviceName === 'DL') return 'Lock'
|
||||
return null
|
||||
}
|
||||
|
||||
test.describe('1. Command API Tests', () => {
|
||||
for (const item of topics) {
|
||||
const { towerNumber, floorName, unitNumber: originalUnit, deviceName, deviceRoom, deviceType } = item
|
||||
const action = getPayload(deviceName)
|
||||
|
||||
if (action) {
|
||||
const unitNumber = numToAlpha(originalUnit)
|
||||
const payload = {
|
||||
merchantName: 'SAVY',
|
||||
floorName,
|
||||
unitNumber,
|
||||
deviceName,
|
||||
roomName: deviceRoom,
|
||||
deviceType,
|
||||
commandType: 'C',
|
||||
towerNumber,
|
||||
payload: { action }
|
||||
}
|
||||
|
||||
test(`POST Command: ${deviceName} (${deviceType}) - ${floorName}_${unitNumber} - ${deviceRoom}`, async ({ request }) => {
|
||||
const { timestamp, nonce, signature } = generateSignatureForPost(payload)
|
||||
|
||||
console.log(`[Command] Request: ${JSON.stringify(payload, null, 2)}`)
|
||||
|
||||
const response = await request.post(`${API_URL}${API_COMMAND_PATH}`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-Key': API_KEY,
|
||||
'X-Timestamp': timestamp.toString(),
|
||||
'X-Nonce': nonce,
|
||||
'X-Signature': signature
|
||||
},
|
||||
data: payload
|
||||
})
|
||||
|
||||
const responseBody = await response.json()
|
||||
console.log(`[Command] Response Status: ${response.status()}`)
|
||||
console.log(`[Command] Response Body: ${JSON.stringify(responseBody, null, 2)}`)
|
||||
console.log('---')
|
||||
|
||||
expect(response.status()).toBe(200)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test.describe('2. Status Check API Tests', () => {
|
||||
for (const item of topics) {
|
||||
const { towerNumber, floorName, unitNumber: originalUnit, deviceName, deviceRoom, deviceType } = item
|
||||
const action = getPayload(deviceName)
|
||||
|
||||
if (action) {
|
||||
const unitNumber = numToAlpha(originalUnit)
|
||||
test(`GET Status: ${deviceName} (${deviceType}) - ${floorName}_${unitNumber} - ${deviceRoom}`, async ({ request }) => {
|
||||
const params = {
|
||||
merchantName: 'SAVY',
|
||||
floorName,
|
||||
unitNumber,
|
||||
deviceName,
|
||||
roomName: deviceRoom,
|
||||
deviceType,
|
||||
commandType: 'S',
|
||||
towerNumber
|
||||
}
|
||||
|
||||
const queryString = new URLSearchParams(params).toString()
|
||||
const url = `${API_URL}${API_STATUS_PATH}?${queryString}`
|
||||
const { timestamp, nonce, signature } = generateSignatureForGet(url)
|
||||
|
||||
console.log(`[Status Check] Request URL: ${url}`)
|
||||
|
||||
const response = await request.get(url, {
|
||||
headers: {
|
||||
'X-API-Key': API_KEY,
|
||||
'X-Timestamp': timestamp.toString(),
|
||||
'X-Nonce': nonce,
|
||||
'X-Signature': signature
|
||||
}
|
||||
})
|
||||
|
||||
const responseBody = await response.json()
|
||||
console.log(`[Status Check] Response Status: ${response.status()}`)
|
||||
console.log(`[Status Check] Response Body: ${JSON.stringify(responseBody, null, 2)}`)
|
||||
console.log('---')
|
||||
|
||||
expect(response.status()).toBe(200)
|
||||
expect(responseBody.data).not.toBeNull()
|
||||
|
||||
// Strict Validation
|
||||
expect(responseBody.data.floorName).toBe(floorName)
|
||||
expect(responseBody.data.unitNumber).toBe(unitNumber)
|
||||
expect(responseBody.data.deviceName).toBe(deviceName)
|
||||
expect(responseBody.data.roomName).toBe(deviceRoom)
|
||||
expect(responseBody.data.deviceType).toBe(deviceType)
|
||||
expect(responseBody.data.code).toBe('S')
|
||||
expect(responseBody.data.towerNumber).toBe(towerNumber)
|
||||
expect(responseBody.data).toHaveProperty('payload')
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
77
tests/command-api.spec.ts
Normal file
77
tests/command-api.spec.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import topics from '../topic.json'
|
||||
|
||||
test.describe('Savy API Automation', () => {
|
||||
|
||||
// Helper to determine payload
|
||||
const getPayload = (deviceName: string) => {
|
||||
if (deviceName === 'AC') return 'AC=On'
|
||||
if (deviceName === 'BL') return 'Bind=Open'
|
||||
if (deviceName === 'DL') return 'Doorlock=Lock'
|
||||
return null
|
||||
}
|
||||
|
||||
test.describe('1. Command API Tests', () => {
|
||||
for (const item of topics) {
|
||||
const { towerNumber, floorName, unitNumber, deviceName, deviceRoom, deviceType } = item
|
||||
const payload = getPayload(deviceName)
|
||||
|
||||
if (payload) {
|
||||
const topic = `SAVY/${floorName}_${unitNumber}-${deviceName}-${deviceRoom}-${deviceType}-C-${towerNumber}`
|
||||
|
||||
test(`Send command for ${deviceName} - ${topic}`, async ({ request }) => {
|
||||
const requestData = { topic, payload }
|
||||
|
||||
console.log(`[Command] Request: ${JSON.stringify(requestData, null, 2)}`)
|
||||
|
||||
const response = await request.post('http://savy.vegacloud.id/command', {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Basic e3thdXRodXNlckhUVFB9fTp7e2F1dGhwd2RIVFRQfX0=',
|
||||
},
|
||||
data: requestData
|
||||
})
|
||||
|
||||
const responseBody = await response.json()
|
||||
console.log(`[Command] Response Status: ${response.status()}`)
|
||||
console.log(`[Command] Response Body: ${JSON.stringify(responseBody, null, 2)}`)
|
||||
console.log('---')
|
||||
|
||||
expect(response.status()).toBe(200)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test.describe('2. State Reply API Tests', () => {
|
||||
for (const item of topics) {
|
||||
const { towerNumber, floorName, unitNumber, deviceName, deviceRoom, deviceType } = item
|
||||
const payload = getPayload(deviceName)
|
||||
|
||||
if (payload) {
|
||||
const topic = `SAVY/${floorName}_${unitNumber}-${deviceName}-${deviceRoom}-${deviceType}-S-${towerNumber}`
|
||||
|
||||
test(`Check state for ${deviceName} - ${topic}`, async ({ request }) => {
|
||||
const requestData = { topic }
|
||||
|
||||
console.log(`[State Reply] Request: ${JSON.stringify(requestData, null, 2)}`)
|
||||
|
||||
const response = await request.post('http://savy.vegacloud.id/state-reply', {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data: requestData
|
||||
})
|
||||
|
||||
const responseBody = await response.json()
|
||||
console.log(`[State Reply] Response Status: ${response.status()}`)
|
||||
console.log(`[State Reply] Response Body: ${JSON.stringify(responseBody, null, 2)}`)
|
||||
console.log('---')
|
||||
|
||||
expect(response.status()).toBe(200)
|
||||
expect(responseBody.data).not.toBeNull()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
18
tests/example.spec.ts
Normal file
18
tests/example.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('has title', async ({ page }) => {
|
||||
await page.goto('https://playwright.dev/');
|
||||
|
||||
// Expect a title "to contain" a substring.
|
||||
await expect(page).toHaveTitle(/Playwright/);
|
||||
});
|
||||
|
||||
test('get started link', async ({ page }) => {
|
||||
await page.goto('https://playwright.dev/');
|
||||
|
||||
// Click the get started link.
|
||||
await page.getByRole('link', { name: 'Get started' }).click();
|
||||
|
||||
// Expects page to have a heading with the name of Installation.
|
||||
await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
|
||||
});
|
||||
154
topic.json
Normal file
154
topic.json
Normal file
@@ -0,0 +1,154 @@
|
||||
[
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "L",
|
||||
"deviceRoom": "LV",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "L",
|
||||
"deviceRoom": "MS",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "L",
|
||||
"deviceRoom": "BT",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "L",
|
||||
"deviceRoom": "WIC",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "BL",
|
||||
"deviceRoom": "LV",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "BL",
|
||||
"deviceRoom": "MS",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "AC",
|
||||
"deviceRoom": "LV",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "AC",
|
||||
"deviceRoom": "LV",
|
||||
"deviceType": "A"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "AC",
|
||||
"deviceRoom": "BR1",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "AC",
|
||||
"deviceRoom": "BR1",
|
||||
"deviceType": "A"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "AC",
|
||||
"deviceRoom": "BR2",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "AC",
|
||||
"deviceRoom": "BR2",
|
||||
"deviceType": "A"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "AC",
|
||||
"deviceRoom": "MS",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "AC",
|
||||
"deviceRoom": "MS",
|
||||
"deviceType": "A"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "FT1",
|
||||
"deviceRoom": "LV",
|
||||
"deviceType": "A"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "FT2",
|
||||
"deviceRoom": "LV",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "PM25",
|
||||
"deviceRoom": "LV",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "DL",
|
||||
"deviceRoom": "KN",
|
||||
"deviceType": "S"
|
||||
},
|
||||
{
|
||||
"towerNumber": "T2",
|
||||
"floorName": "L29",
|
||||
"unitNumber": "05",
|
||||
"deviceName": "KC",
|
||||
"deviceRoom": "KN",
|
||||
"deviceType": "S"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user