From 324463e3b1ae0812202668ebeacdd1f13c4b7b64 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Wed, 6 Nov 2024 01:33:41 +0800 Subject: [PATCH 01/35] branch name --- apps/signalling-service/.dockerignore | 9 ++++++ apps/signalling-service/pnpm-lock.yaml | 40 +++++++++++++++----------- 2 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 apps/signalling-service/.dockerignore diff --git a/apps/signalling-service/.dockerignore b/apps/signalling-service/.dockerignore new file mode 100644 index 0000000000..3f214be645 --- /dev/null +++ b/apps/signalling-service/.dockerignore @@ -0,0 +1,9 @@ +node_modules +.git +.gitignore +README.md +LICENSE +.env +.env* +Dockerfile +.dockerignore \ No newline at end of file diff --git a/apps/signalling-service/pnpm-lock.yaml b/apps/signalling-service/pnpm-lock.yaml index cd6e4916a0..04ce15c614 100644 --- a/apps/signalling-service/pnpm-lock.yaml +++ b/apps/signalling-service/pnpm-lock.yaml @@ -1,32 +1,31 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -dependencies: - lib0: - specifier: ^0.2.98 - version: 0.2.98 - ws: - specifier: ^8.18.0 - version: 8.18.0 +importers: + + .: + dependencies: + lib0: + specifier: ^0.2.98 + version: 0.2.98 + ws: + specifier: ^8.18.0 + version: 8.18.0 packages: - /isomorphic.js@0.2.5: + isomorphic.js@0.2.5: resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} - dev: false - /lib0@0.2.98: + lib0@0.2.98: resolution: {integrity: sha512-XteTiNO0qEXqqweWx+b21p/fBnNHUA1NwAtJNJek1oPrewEZs2uiT4gWivHKr9GqCjDPAhchz0UQO8NwU3bBNA==} engines: {node: '>=16'} hasBin: true - dependencies: - isomorphic.js: 0.2.5 - dev: false - /ws@8.18.0: + ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} peerDependencies: @@ -37,4 +36,13 @@ packages: optional: true utf-8-validate: optional: true - dev: false + +snapshots: + + isomorphic.js@0.2.5: {} + + lib0@0.2.98: + dependencies: + isomorphic.js: 0.2.5 + + ws@8.18.0: {} From ab4cc476f7ba56be6b9e0ef2106133a6b835ac17 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 11:22:05 +0800 Subject: [PATCH 02/35] try selenium test --- .github/workflows/test.yml | 34 +- .../__tests__/browser-tests/browser.test.ts | 44 ++ .../__tests__/browser-tests/works.test.js | 16 + .../{ => unit-tests}/Datetime.test.ts | 0 .../dependencymocking.test.ts | 0 .../{ => unit-tests}/question.test.ts | 0 apps/frontend/package.json | 6 +- apps/frontend/pnpm-lock.yaml | 512 ++++++++++++++++++ 8 files changed, 610 insertions(+), 2 deletions(-) create mode 100644 apps/frontend/__tests__/browser-tests/browser.test.ts create mode 100644 apps/frontend/__tests__/browser-tests/works.test.js rename apps/frontend/__tests__/{ => unit-tests}/Datetime.test.ts (100%) rename apps/frontend/__tests__/{ => unit-tests}/dependencymocking.test.ts (100%) rename apps/frontend/__tests__/{ => unit-tests}/question.test.ts (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 90408360b4..0b843e57a1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -83,10 +83,42 @@ jobs: - name: Run tests run: | cd ./apps/frontend - pnpm test + pnpm test -- __tests__/unit-tests + + browser-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '22' + + - name: Install pnpm + run: npm i -g pnpm + + - name: Install dependencies + run: | + cd ./apps/frontend + pnpm i + + - name: Run tests + run: | + cd ./apps/frontend + node .\__tests__\browser-tests\wtf.test.js + + test-docker-compose: runs-on: ubuntu-latest + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Chrome Driver + run: | steps: - name: Checkout code diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts new file mode 100644 index 0000000000..dee5121683 --- /dev/null +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -0,0 +1,44 @@ +import { Browser, Builder, By, Key, until } from "selenium-webdriver" + +import { path } from "chromedriver" +import { getBinaryPaths } from "selenium-webdriver/common/driverFinder" +import Chrome from "selenium-webdriver/chrome" +describe("base selenium test", () => { + it.skip("works", async () => { + // referenced: https://www.npmjs.com/package/selenium-webdriver + console.log(path) + + let options = new Chrome.Options(); + options.setBrowserVersion("stable") + + let paths = getBinaryPaths(options) + let driverPath = paths.driverPath; + let browserPath = paths.browserPath; + console.log(paths); + + options.setChromeBinaryPath(browserPath) + + let service = new Chrome.ServiceBuilder().setPath(driverPath); + + let driver = await new Builder().forBrowser(Browser.CHROME) + .setChromeOptions(options) + .setChromeService(service) + .build(); + + console.log("got here"); + + try { + await driver.get('https://www.google.com/ncr') + console.log("got here"); + await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN) + console.log("got here"); + await driver.wait(until.titleIs('webdriver - Google Search'), 1000) + console.log("got here"); + } finally { + await driver.quit() + } + }, 60000) +}) + + + diff --git a/apps/frontend/__tests__/browser-tests/works.test.js b/apps/frontend/__tests__/browser-tests/works.test.js new file mode 100644 index 0000000000..4f902bd48b --- /dev/null +++ b/apps/frontend/__tests__/browser-tests/works.test.js @@ -0,0 +1,16 @@ +// require('chromedriver'); +const { Builder, By, Key, until } = require('selenium-webdriver'); +(async function test() { + const builder = new Builder().forBrowser('chrome'); + console.log(builder.getChromeOptions()); + + let driver = await builder.build(); + + try { + await driver.get('http://www.google.com'); + await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); + await driver.wait(until.titleIs('webdriver - Google Search'), 1000); + } finally { + await driver.quit(); + } +})(); \ No newline at end of file diff --git a/apps/frontend/__tests__/Datetime.test.ts b/apps/frontend/__tests__/unit-tests/Datetime.test.ts similarity index 100% rename from apps/frontend/__tests__/Datetime.test.ts rename to apps/frontend/__tests__/unit-tests/Datetime.test.ts diff --git a/apps/frontend/__tests__/dependencymocking.test.ts b/apps/frontend/__tests__/unit-tests/dependencymocking.test.ts similarity index 100% rename from apps/frontend/__tests__/dependencymocking.test.ts rename to apps/frontend/__tests__/unit-tests/dependencymocking.test.ts diff --git a/apps/frontend/__tests__/question.test.ts b/apps/frontend/__tests__/unit-tests/question.test.ts similarity index 100% rename from apps/frontend/__tests__/question.test.ts rename to apps/frontend/__tests__/unit-tests/question.test.ts diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 792fc18474..da143a8b4d 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -37,19 +37,23 @@ "yjs": "^13.6.20" }, "devDependencies": { - "@types/codemirror": "^5.60.15", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.0.1", + "@types/chromedriver": "^81.0.5", + "@types/codemirror": "^5.60.15", "@types/jest": "^29.5.14", "@types/node": "^20", "@types/peerjs": "^1.1.0", "@types/react": "^18.3.8", "@types/react-dom": "^18.3.0", + "@types/selenium-webdriver": "^4.1.27", + "chromedriver": "^130.0.4", "eslint": "^8", "eslint-config-next": "14.2.13", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", + "selenium-webdriver": "^4.26.0", "ts-node": "^10.9.2", "typescript": "^5" }, diff --git a/apps/frontend/pnpm-lock.yaml b/apps/frontend/pnpm-lock.yaml index 413f0c29e3..4a85647726 100644 --- a/apps/frontend/pnpm-lock.yaml +++ b/apps/frontend/pnpm-lock.yaml @@ -93,6 +93,9 @@ importers: '@testing-library/react': specifier: ^16.0.1 version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@types/chromedriver': + specifier: ^81.0.5 + version: 81.0.5 '@types/codemirror': specifier: ^5.60.15 version: 5.60.15 @@ -111,6 +114,12 @@ importers: '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 + '@types/selenium-webdriver': + specifier: ^4.1.27 + version: 4.1.27 + chromedriver: + specifier: ^130.0.4 + version: 130.0.4 eslint: specifier: ^8 version: 8.0.0 @@ -123,6 +132,9 @@ importers: jest-environment-jsdom: specifier: ^29.7.0 version: 29.7.0 + selenium-webdriver: + specifier: ^4.26.0 + version: 4.26.0 ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@20.0.0)(typescript@5.0.2) @@ -344,6 +356,9 @@ packages: resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} + '@bazel/runfiles@6.3.1': + resolution: {integrity: sha512-1uLNT5NZsUVIGS4syuHwTzZ8HycMPyr6POA3FCE4GbMtc4rhoJk8aZKtNIRthJYfL+iioppi+rTfH3olMPr9nA==} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -708,6 +723,9 @@ packages: '@swc/helpers@0.5.5': resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} + '@testim/chrome-version@1.1.4': + resolution: {integrity: sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==} + '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} @@ -735,6 +753,9 @@ packages: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} + '@tootallnate/quickjs-emscripten@0.23.0': + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@tsconfig/node10@1.0.11': resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} @@ -762,6 +783,9 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/chromedriver@81.0.5': + resolution: {integrity: sha512-VwV+WTTFHYZotBn57QQ8gd4TE7CGJ15KPM+xJJrKbiQQSccTY7zVXuConSBlyWrO+AFpVxuzmluK3xvzxGmkCw==} + '@types/codemirror@5.60.15': resolution: {integrity: sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==} @@ -805,6 +829,9 @@ packages: '@types/react@18.3.8': resolution: {integrity: sha512-syBUrW3/XpnW4WJ41Pft+I+aPoDVbrBVQGEnbD7NijDGlVC+8gV/XKRY+7vMDlfPpbwYt0l1vd/Sj8bJGMbs9Q==} + '@types/selenium-webdriver@4.1.27': + resolution: {integrity: sha512-ALqsj8D7Swb6MnBQuAQ58J3KC3yh6fLGtAmpBmnZX8j+0kmP7NaLt56CuzBw2W2bXPrvHFTgn8iekOQFUKXEQA==} + '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} @@ -814,12 +841,18 @@ packages: '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/ws@8.5.13': + resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@typescript-eslint/eslint-plugin@8.8.0': resolution: {integrity: sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -902,6 +935,10 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} + agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -996,6 +1033,10 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -1007,6 +1048,9 @@ packages: resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==} engines: {node: '>=4'} + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -1042,6 +1086,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + basic-ftp@5.0.5: + resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} + engines: {node: '>=10.0.0'} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -1060,6 +1108,9 @@ packages: bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -1108,6 +1159,11 @@ packages: resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} engines: {node: '>= 14.16.0'} + chromedriver@130.0.4: + resolution: {integrity: sha512-lpR+PWXszij1k4Ig3t338Zvll9HtCTiwoLM7n4pCCswALHxzmgwaaIFBh3rt9+5wRk9D07oFblrazrBxwaYYAQ==} + engines: {node: '>=18'} + hasBin: true + ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -1146,6 +1202,9 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + compute-scroll-into-view@3.1.0: resolution: {integrity: sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==} @@ -1158,6 +1217,9 @@ packages: copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + create-jest@29.7.0: resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1192,6 +1254,10 @@ packages: damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} + data-urls@3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} @@ -1219,6 +1285,15 @@ packages: supports-color: optional: true + debug@4.3.1: + resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} @@ -1258,6 +1333,10 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -1313,6 +1392,9 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + enhanced-resolve@5.17.1: resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} @@ -1519,6 +1601,11 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1538,6 +1625,9 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -1557,6 +1647,15 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -1568,6 +1667,10 @@ packages: resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1608,6 +1711,10 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -1619,6 +1726,10 @@ packages: get-tsconfig@4.8.1: resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + get-uri@6.0.3: + resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==} + engines: {node: '>= 14'} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1694,10 +1805,18 @@ packages: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} + https-proxy-agent@7.0.5: + resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} + engines: {node: '>= 14'} + human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -1717,6 +1836,9 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + immutable@4.3.7: resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} @@ -1748,6 +1870,14 @@ packages: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + + ip-regex@4.3.0: + resolution: {integrity: sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==} + engines: {node: '>=8'} + is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -1859,6 +1989,9 @@ packages: resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -1870,6 +2003,13 @@ packages: resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} engines: {node: '>= 0.4'} + is2@2.0.9: + resolution: {integrity: sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==} + engines: {node: '>=v0.10.0'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -2059,6 +2199,9 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + jsdom@20.0.3: resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} engines: {node: '>=14'} @@ -2097,10 +2240,16 @@ packages: engines: {node: '>=6'} hasBin: true + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + jwt-decode@4.0.0: resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} engines: {node: '>=18'} @@ -2132,6 +2281,9 @@ packages: engines: {node: '>=16'} hasBin: true + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -2155,6 +2307,10 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -2210,6 +2366,9 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2221,6 +2380,10 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + next@14.2.13: resolution: {integrity: sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg==} engines: {node: '>=18.17.0'} @@ -2319,6 +2482,17 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + pac-proxy-agent@7.0.2: + resolution: {integrity: sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==} + engines: {node: '>= 14'} + + pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} + engines: {node: '>= 14'} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2357,6 +2531,9 @@ packages: resolution: {integrity: sha512-yFsoLMnurJKlQbx6kVSBpOp+AlNldY1JQS2BrSsHLKCZnq6t7saHleuHM5svuLNbQkUJXHLF3sKOJB1K0xulOw==} engines: {node: '>= 14'} + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} @@ -2392,6 +2569,9 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -2403,9 +2583,19 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proxy-agent@6.4.0: + resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} + engines: {node: '>= 14'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2676,6 +2866,9 @@ packages: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -2756,6 +2949,9 @@ packages: resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -2784,6 +2980,10 @@ packages: sdp@3.2.0: resolution: {integrity: sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==} + selenium-webdriver@4.26.0: + resolution: {integrity: sha512-nA7jMRIPV17mJmAiTDBWN96Sy0Uxrz5CCLb7bLVV6PpL417SyBMPc2Zo/uoREc2EOHlzHwHwAlFtgmSngSY4WQ==} + engines: {node: '>= 14.21.0'} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2801,6 +3001,9 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2830,6 +3033,18 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@8.0.4: + resolution: {integrity: sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==} + engines: {node: '>= 14'} + + socks@2.8.3: + resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2844,6 +3059,9 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -2892,6 +3110,9 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -2961,6 +3182,9 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + tcp-port-used@1.0.2: + resolution: {integrity: sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==} + test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -2972,6 +3196,10 @@ packages: resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} engines: {node: '>=12.22'} + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -3063,6 +3291,10 @@ packages: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -3211,6 +3443,9 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + yjs@13.6.20: resolution: {integrity: sha512-Z2YZI+SYqK7XdWlloI3lhMiKnCdFCVC4PchpdO+mCYwtiTwncjUbnRK9R1JmkNfdmHyDXuWN3ibJAt0wsqTbLQ==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} @@ -3478,6 +3713,8 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@bazel/runfiles@6.3.1': {} + '@bcoe/v8-coverage@0.2.3': {} '@codemirror/autocomplete@6.18.1(@codemirror/language@6.10.3)(@codemirror/state@6.4.1)(@codemirror/view@6.34.1)(@lezer/common@1.2.3)': @@ -3989,6 +4226,8 @@ snapshots: '@swc/counter': 0.1.3 tslib: 2.7.0 + '@testim/chrome-version@1.1.4': {} + '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.26.2 @@ -4022,6 +4261,8 @@ snapshots: '@tootallnate/once@2.0.0': {} + '@tootallnate/quickjs-emscripten@0.23.0': {} + '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -4053,6 +4294,10 @@ snapshots: dependencies: '@babel/types': 7.26.0 + '@types/chromedriver@81.0.5': + dependencies: + '@types/node': 20.0.0 + '@types/codemirror@5.60.15': dependencies: '@types/tern': 0.23.9 @@ -4103,6 +4348,11 @@ snapshots: '@types/prop-types': 15.7.13 csstype: 3.1.3 + '@types/selenium-webdriver@4.1.27': + dependencies: + '@types/node': 20.0.0 + '@types/ws': 8.5.13 + '@types/stack-utils@2.0.3': {} '@types/tern@0.23.9': @@ -4111,12 +4361,21 @@ snapshots: '@types/tough-cookie@4.0.5': {} + '@types/ws@8.5.13': + dependencies: + '@types/node': 20.0.0 + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.33': dependencies: '@types/yargs-parser': 21.0.3 + '@types/yauzl@2.10.3': + dependencies: + '@types/node': 20.0.0 + optional: true + '@typescript-eslint/eslint-plugin@8.8.0(@typescript-eslint/parser@8.8.0(eslint@8.0.0)(typescript@5.0.2))(eslint@8.0.0)(typescript@5.0.2)': dependencies: '@eslint-community/regexpp': 4.11.1 @@ -4221,6 +4480,12 @@ snapshots: transitivePeerDependencies: - supports-color + agent-base@7.1.1: + dependencies: + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -4394,6 +4659,10 @@ snapshots: ast-types-flow@0.0.8: {} + ast-types@0.13.4: + dependencies: + tslib: 2.7.0 + asynckit@0.4.0: {} available-typed-arrays@1.0.7: @@ -4402,6 +4671,14 @@ snapshots: axe-core@4.10.0: {} + axios@1.7.7: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axobject-query@4.1.0: {} babel-jest@29.7.0(@babel/core@7.26.0): @@ -4463,6 +4740,8 @@ snapshots: base64-js@1.5.1: {} + basic-ftp@5.0.5: {} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -4487,6 +4766,8 @@ snapshots: dependencies: node-int64: 0.4.0 + buffer-crc32@0.2.13: {} + buffer-from@1.1.2: {} buffer@6.0.3: @@ -4532,6 +4813,19 @@ snapshots: dependencies: readdirp: 4.0.1 + chromedriver@130.0.4: + dependencies: + '@testim/chrome-version': 1.1.4 + axios: 1.7.7 + compare-versions: 6.1.1 + extract-zip: 2.0.1 + proxy-agent: 6.4.0 + proxy-from-env: 1.1.0 + tcp-port-used: 1.0.2 + transitivePeerDependencies: + - debug + - supports-color + ci-info@3.9.0: {} cjs-module-lexer@1.4.1: {} @@ -4572,6 +4866,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 + compare-versions@6.1.1: {} + compute-scroll-into-view@3.1.0: {} concat-map@0.0.1: {} @@ -4582,6 +4878,8 @@ snapshots: dependencies: toggle-selection: 1.0.6 + core-util-is@1.0.3: {} + create-jest@29.7.0(@types/node@20.0.0)(ts-node@10.9.2(@types/node@20.0.0)(typescript@5.0.2)): dependencies: '@jest/types': 29.6.3 @@ -4621,6 +4919,8 @@ snapshots: damerau-levenshtein@1.0.8: {} + data-uri-to-buffer@6.0.2: {} + data-urls@3.0.2: dependencies: abab: 2.0.6 @@ -4651,6 +4951,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.3.1: + dependencies: + ms: 2.1.2 + debug@4.3.7: dependencies: ms: 2.1.3 @@ -4696,6 +5000,12 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + degenerator@5.0.1: + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + delayed-stream@1.0.0: {} dequal@2.0.3: {} @@ -4732,6 +5042,10 @@ snapshots: emoji-regex@9.2.2: {} + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + enhanced-resolve@5.17.1: dependencies: graceful-fs: 4.2.11 @@ -5101,6 +5415,16 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 + extract-zip@2.0.1: + dependencies: + debug: 4.3.7 + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + fast-deep-equal@3.1.3: {} fast-glob@3.3.2: @@ -5123,6 +5447,10 @@ snapshots: dependencies: bser: 2.1.1 + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 @@ -5144,6 +5472,8 @@ snapshots: flatted@3.3.1: {} + follow-redirects@1.15.9: {} + for-each@0.3.3: dependencies: is-callable: 1.2.7 @@ -5159,6 +5489,12 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -5193,6 +5529,10 @@ snapshots: get-package-type@0.1.0: {} + get-stream@5.2.0: + dependencies: + pump: 3.0.2 + get-stream@6.0.1: {} get-symbol-description@1.0.2: @@ -5205,6 +5545,15 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + get-uri@6.0.3: + dependencies: + basic-ftp: 5.0.5 + data-uri-to-buffer: 6.0.2 + debug: 4.3.7 + fs-extra: 11.2.0 + transitivePeerDependencies: + - supports-color + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -5283,6 +5632,13 @@ snapshots: transitivePeerDependencies: - supports-color + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.1 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -5290,6 +5646,13 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@7.0.5: + dependencies: + agent-base: 7.1.1 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + human-signals@2.1.0: {} iconv-lite@0.6.3: @@ -5302,6 +5665,8 @@ snapshots: ignore@5.3.2: {} + immediate@3.0.6: {} + immutable@4.3.7: {} import-fresh@3.3.0: @@ -5331,6 +5696,13 @@ snapshots: hasown: 2.0.2 side-channel: 1.0.6 + ip-address@9.0.5: + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 + + ip-regex@4.3.0: {} + is-arguments@1.1.1: dependencies: call-bind: 1.0.7 @@ -5429,6 +5801,8 @@ snapshots: dependencies: which-typed-array: 1.1.15 + is-url@1.2.4: {} + is-weakmap@2.0.2: {} is-weakref@1.0.2: @@ -5440,6 +5814,14 @@ snapshots: call-bind: 1.0.7 get-intrinsic: 1.2.4 + is2@2.0.9: + dependencies: + deep-is: 0.1.4 + ip-regex: 4.3.0 + is-url: 1.2.4 + + isarray@1.0.0: {} + isarray@2.0.5: {} isexe@2.0.0: {} @@ -5836,6 +6218,8 @@ snapshots: dependencies: argparse: 2.0.1 + jsbn@1.1.0: {} + jsdom@20.0.3: dependencies: abab: 2.0.6 @@ -5889,6 +6273,12 @@ snapshots: json5@2.2.3: {} + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -5896,6 +6286,13 @@ snapshots: object.assign: 4.1.5 object.values: 1.2.0 + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + jwt-decode@4.0.0: {} keyv@4.5.4: @@ -5921,6 +6318,10 @@ snapshots: dependencies: isomorphic.js: 0.2.5 + lie@3.3.0: + dependencies: + immediate: 3.0.6 + lines-and-columns@1.2.4: {} locate-path@5.0.0: @@ -5941,6 +6342,8 @@ snapshots: dependencies: yallist: 3.1.1 + lru-cache@7.18.3: {} + lz-string@1.5.0: {} make-dir@4.0.0: @@ -5984,12 +6387,16 @@ snapshots: minipass@7.1.2: {} + ms@2.1.2: {} + ms@2.1.3: {} nanoid@3.3.7: {} natural-compare@1.4.0: {} + netmask@2.0.2: {} + next@14.2.13(@babel/core@7.26.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.79.2): dependencies: '@next/env': 14.2.13 @@ -6102,6 +6509,26 @@ snapshots: p-try@2.2.0: {} + pac-proxy-agent@7.0.2: + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.1 + debug: 4.3.7 + get-uri: 6.0.3 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.5 + pac-resolver: 7.0.1 + socks-proxy-agent: 8.0.4 + transitivePeerDependencies: + - supports-color + + pac-resolver@7.0.1: + dependencies: + degenerator: 5.0.1 + netmask: 2.0.2 + + pako@1.0.11: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -6139,6 +6566,8 @@ snapshots: peerjs-js-binarypack: 2.1.0 webrtc-adapter: 9.0.1 + pend@1.2.0: {} + picocolors@1.1.0: {} picomatch@2.3.1: {} @@ -6171,6 +6600,8 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + process-nextick-args@2.0.1: {} + progress@2.0.3: {} prompts@2.4.2: @@ -6184,8 +6615,28 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proxy-agent@6.4.0: + dependencies: + agent-base: 7.1.1 + debug: 4.3.7 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.5 + lru-cache: 7.18.3 + pac-proxy-agent: 7.0.2 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.4 + transitivePeerDependencies: + - supports-color + + proxy-from-env@1.1.0: {} + psl@1.9.0: {} + pump@3.0.2: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + punycode@2.3.1: {} pure-rand@6.1.0: {} @@ -6539,6 +6990,16 @@ snapshots: dependencies: loose-envify: 1.4.0 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -6620,6 +7081,8 @@ snapshots: has-symbols: 1.0.3 isarray: 2.0.5 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safe-regex-test@1.0.3: @@ -6650,6 +7113,16 @@ snapshots: sdp@3.2.0: {} + selenium-webdriver@4.26.0: + dependencies: + '@bazel/runfiles': 6.3.1 + jszip: 3.10.1 + tmp: 0.2.3 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + semver@6.3.1: {} semver@7.6.3: {} @@ -6670,6 +7143,8 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + setimmediate@1.0.5: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -6703,6 +7178,21 @@ snapshots: slash@3.0.0: {} + smart-buffer@4.2.0: {} + + socks-proxy-agent@8.0.4: + dependencies: + agent-base: 7.1.1 + debug: 4.3.7 + socks: 2.8.3 + transitivePeerDependencies: + - supports-color + + socks@2.8.3: + dependencies: + ip-address: 9.0.5 + smart-buffer: 4.2.0 + source-map-js@1.2.1: {} source-map-support@0.5.13: @@ -6714,6 +7204,8 @@ snapshots: sprintf-js@1.0.3: {} + sprintf-js@1.1.3: {} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -6787,6 +7279,10 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.0.0 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -6836,6 +7332,13 @@ snapshots: tapable@2.2.1: {} + tcp-port-used@1.0.2: + dependencies: + debug: 4.3.1 + is2: 2.0.9 + transitivePeerDependencies: + - supports-color + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 @@ -6846,6 +7349,8 @@ snapshots: throttle-debounce@5.0.2: {} + tmp@0.2.3: {} + tmpl@1.0.5: {} to-regex-range@5.0.1: @@ -6951,6 +7456,8 @@ snapshots: universalify@0.2.0: {} + universalify@2.0.1: {} + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: browserslist: 4.24.2 @@ -7115,6 +7622,11 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + yjs@13.6.20: dependencies: lib0: 0.2.98 From 8958cb6151a2423236ab8c5527ddc464b5185079 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 11:23:29 +0800 Subject: [PATCH 03/35] asd --- .github/workflows/test.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0b843e57a1..70da397075 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -114,11 +114,6 @@ jobs: test-docker-compose: runs-on: ubuntu-latest - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install Chrome Driver - run: | steps: - name: Checkout code From 240c839afa0bd5fc4690b9c2e8d0b74f45d69b59 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 11:27:52 +0800 Subject: [PATCH 04/35] asd --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 70da397075..d0b82b8f51 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -108,7 +108,7 @@ jobs: - name: Run tests run: | cd ./apps/frontend - node .\__tests__\browser-tests\wtf.test.js + node ./__tests__/browser-tests\wtf.test.js From 5b79d8be4f25309d4cfe05a61d5a406ddfccf0c6 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 11:28:49 +0800 Subject: [PATCH 05/35] asd --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d0b82b8f51..09d5ad6c0f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -108,7 +108,7 @@ jobs: - name: Run tests run: | cd ./apps/frontend - node ./__tests__/browser-tests\wtf.test.js + node ./__tests__/browser-tests/wtf.test.js From 67960833336c4c9818983f855ad11d72eb03b454 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 11:32:00 +0800 Subject: [PATCH 06/35] asd --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 09d5ad6c0f..6e099d6ab0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -108,7 +108,7 @@ jobs: - name: Run tests run: | cd ./apps/frontend - node ./__tests__/browser-tests/wtf.test.js + node ./__tests__/browser-tests/works.test.js From 9f1efaffdee71440839ca67e2ed7f39e1c0bec9a Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 11:55:18 +0800 Subject: [PATCH 07/35] asd s --- apps/frontend/__tests__/browser-tests/works.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/frontend/__tests__/browser-tests/works.test.js b/apps/frontend/__tests__/browser-tests/works.test.js index 4f902bd48b..fe98294e90 100644 --- a/apps/frontend/__tests__/browser-tests/works.test.js +++ b/apps/frontend/__tests__/browser-tests/works.test.js @@ -1,7 +1,8 @@ -// require('chromedriver'); +require('chromedriver'); const { Builder, By, Key, until } = require('selenium-webdriver'); (async function test() { const builder = new Builder().forBrowser('chrome'); + console.log(builder.getChromeOptions()); let driver = await builder.build(); From cc46721c40d11b60c05287e0facbc9c69a0399a7 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 13:47:37 +0800 Subject: [PATCH 08/35] asd --- .github/workflows/test.yml | 6 +- .../__tests__/browser-tests/browser.test.ts | 43 +- .../__tests__/browser-tests/works.test.js | 17 - apps/frontend/package.json | 1 - apps/frontend/pnpm-lock.yaml | 384 ------------------ 5 files changed, 16 insertions(+), 435 deletions(-) delete mode 100644 apps/frontend/__tests__/browser-tests/works.test.js diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6e099d6ab0..dcb13886eb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -105,10 +105,14 @@ jobs: cd ./apps/frontend pnpm i + - uses: nanasess/setup-chromedriver@v2 + with: + chromedriver-version: '130.0.6723.116' + - name: Run tests run: | cd ./apps/frontend - node ./__tests__/browser-tests/works.test.js + pnpm test -- ./__tests__/browser-tests diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index dee5121683..a8227c6c77 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -1,44 +1,23 @@ import { Browser, Builder, By, Key, until } from "selenium-webdriver" -import { path } from "chromedriver" -import { getBinaryPaths } from "selenium-webdriver/common/driverFinder" import Chrome from "selenium-webdriver/chrome" -describe("base selenium test", () => { - it.skip("works", async () => { - // referenced: https://www.npmjs.com/package/selenium-webdriver - console.log(path) - - let options = new Chrome.Options(); - options.setBrowserVersion("stable") - - let paths = getBinaryPaths(options) - let driverPath = paths.driverPath; - let browserPath = paths.browserPath; - console.log(paths); - - options.setChromeBinaryPath(browserPath) - - let service = new Chrome.ServiceBuilder().setPath(driverPath); - let driver = await new Builder().forBrowser(Browser.CHROME) - .setChromeOptions(options) - .setChromeService(service) - .build(); +describe("chrome webdriver installed correctly", () => { + it("does google search", async function test() { + const options = new Chrome.Options().addArguments("--headless=new") as Chrome.Options; + const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); - console.log("got here"); + const driver = await builder.build(); try { - await driver.get('https://www.google.com/ncr') - console.log("got here"); - await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN) - console.log("got here"); - await driver.wait(until.titleIs('webdriver - Google Search'), 1000) - console.log("got here"); + await driver.get('http://www.google.com'); + await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); + await driver.wait(until.titleIs('webdriver - Google Search'), 1000); } finally { - await driver.quit() + await driver.quit(); } - }, 60000) -}) + }); +}); diff --git a/apps/frontend/__tests__/browser-tests/works.test.js b/apps/frontend/__tests__/browser-tests/works.test.js deleted file mode 100644 index fe98294e90..0000000000 --- a/apps/frontend/__tests__/browser-tests/works.test.js +++ /dev/null @@ -1,17 +0,0 @@ -require('chromedriver'); -const { Builder, By, Key, until } = require('selenium-webdriver'); -(async function test() { - const builder = new Builder().forBrowser('chrome'); - - console.log(builder.getChromeOptions()); - - let driver = await builder.build(); - - try { - await driver.get('http://www.google.com'); - await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); - await driver.wait(until.titleIs('webdriver - Google Search'), 1000); - } finally { - await driver.quit(); - } -})(); \ No newline at end of file diff --git a/apps/frontend/package.json b/apps/frontend/package.json index da143a8b4d..34cedd361d 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -48,7 +48,6 @@ "@types/react": "^18.3.8", "@types/react-dom": "^18.3.0", "@types/selenium-webdriver": "^4.1.27", - "chromedriver": "^130.0.4", "eslint": "^8", "eslint-config-next": "14.2.13", "jest": "^29.7.0", diff --git a/apps/frontend/pnpm-lock.yaml b/apps/frontend/pnpm-lock.yaml index 4a85647726..5b99c479b6 100644 --- a/apps/frontend/pnpm-lock.yaml +++ b/apps/frontend/pnpm-lock.yaml @@ -117,9 +117,6 @@ importers: '@types/selenium-webdriver': specifier: ^4.1.27 version: 4.1.27 - chromedriver: - specifier: ^130.0.4 - version: 130.0.4 eslint: specifier: ^8 version: 8.0.0 @@ -723,9 +720,6 @@ packages: '@swc/helpers@0.5.5': resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} - '@testim/chrome-version@1.1.4': - resolution: {integrity: sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==} - '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} @@ -753,9 +747,6 @@ packages: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} - '@tootallnate/quickjs-emscripten@0.23.0': - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - '@tsconfig/node10@1.0.11': resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} @@ -850,9 +841,6 @@ packages: '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@types/yauzl@2.10.3': - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.8.0': resolution: {integrity: sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -935,10 +923,6 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} - agent-base@7.1.1: - resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} - engines: {node: '>= 14'} - ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -1033,10 +1017,6 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} - asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -1048,9 +1028,6 @@ packages: resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==} engines: {node: '>=4'} - axios@1.7.7: - resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} - axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -1086,10 +1063,6 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - basic-ftp@5.0.5: - resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} - engines: {node: '>=10.0.0'} - brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -1108,9 +1081,6 @@ packages: bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -1159,11 +1129,6 @@ packages: resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} engines: {node: '>= 14.16.0'} - chromedriver@130.0.4: - resolution: {integrity: sha512-lpR+PWXszij1k4Ig3t338Zvll9HtCTiwoLM7n4pCCswALHxzmgwaaIFBh3rt9+5wRk9D07oFblrazrBxwaYYAQ==} - engines: {node: '>=18'} - hasBin: true - ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -1202,9 +1167,6 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - compare-versions@6.1.1: - resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - compute-scroll-into-view@3.1.0: resolution: {integrity: sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==} @@ -1254,10 +1216,6 @@ packages: damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} - data-urls@3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} @@ -1285,15 +1243,6 @@ packages: supports-color: optional: true - debug@4.3.1: - resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} @@ -1333,10 +1282,6 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -1392,9 +1337,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enhanced-resolve@5.17.1: resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} @@ -1601,11 +1543,6 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1625,9 +1562,6 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -1647,15 +1581,6 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -1667,10 +1592,6 @@ packages: resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1711,10 +1632,6 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} - get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -1726,10 +1643,6 @@ packages: get-tsconfig@4.8.1: resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} - get-uri@6.0.3: - resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==} - engines: {node: '>= 14'} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1805,18 +1718,10 @@ packages: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} - http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} - https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} - https-proxy-agent@7.0.5: - resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} - engines: {node: '>= 14'} - human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -1870,14 +1775,6 @@ packages: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} - ip-address@9.0.5: - resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} - engines: {node: '>= 12'} - - ip-regex@4.3.0: - resolution: {integrity: sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==} - engines: {node: '>=8'} - is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -1989,9 +1886,6 @@ packages: resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} - is-url@1.2.4: - resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} - is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -2003,10 +1897,6 @@ packages: resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} engines: {node: '>= 0.4'} - is2@2.0.9: - resolution: {integrity: sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==} - engines: {node: '>=v0.10.0'} - isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -2199,9 +2089,6 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsbn@1.1.0: - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - jsdom@20.0.3: resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} engines: {node: '>=14'} @@ -2240,9 +2127,6 @@ packages: engines: {node: '>=6'} hasBin: true - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -2307,10 +2191,6 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -2366,9 +2246,6 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2380,10 +2257,6 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - netmask@2.0.2: - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} - engines: {node: '>= 0.4.0'} - next@14.2.13: resolution: {integrity: sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg==} engines: {node: '>=18.17.0'} @@ -2482,14 +2355,6 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - pac-proxy-agent@7.0.2: - resolution: {integrity: sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==} - engines: {node: '>= 14'} - - pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} - pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -2531,9 +2396,6 @@ packages: resolution: {integrity: sha512-yFsoLMnurJKlQbx6kVSBpOp+AlNldY1JQS2BrSsHLKCZnq6t7saHleuHM5svuLNbQkUJXHLF3sKOJB1K0xulOw==} engines: {node: '>= 14'} - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} @@ -2583,19 +2445,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - proxy-agent@6.4.0: - resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} - engines: {node: '>= 14'} - - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -3033,18 +2885,6 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - - socks-proxy-agent@8.0.4: - resolution: {integrity: sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==} - engines: {node: '>= 14'} - - socks@2.8.3: - resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -3059,9 +2899,6 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -3182,9 +3019,6 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tcp-port-used@1.0.2: - resolution: {integrity: sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==} - test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -3291,10 +3125,6 @@ packages: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -3443,9 +3273,6 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - yjs@13.6.20: resolution: {integrity: sha512-Z2YZI+SYqK7XdWlloI3lhMiKnCdFCVC4PchpdO+mCYwtiTwncjUbnRK9R1JmkNfdmHyDXuWN3ibJAt0wsqTbLQ==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} @@ -4226,8 +4053,6 @@ snapshots: '@swc/counter': 0.1.3 tslib: 2.7.0 - '@testim/chrome-version@1.1.4': {} - '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.26.2 @@ -4261,8 +4086,6 @@ snapshots: '@tootallnate/once@2.0.0': {} - '@tootallnate/quickjs-emscripten@0.23.0': {} - '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -4371,11 +4194,6 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@types/yauzl@2.10.3': - dependencies: - '@types/node': 20.0.0 - optional: true - '@typescript-eslint/eslint-plugin@8.8.0(@typescript-eslint/parser@8.8.0(eslint@8.0.0)(typescript@5.0.2))(eslint@8.0.0)(typescript@5.0.2)': dependencies: '@eslint-community/regexpp': 4.11.1 @@ -4480,12 +4298,6 @@ snapshots: transitivePeerDependencies: - supports-color - agent-base@7.1.1: - dependencies: - debug: 4.3.7 - transitivePeerDependencies: - - supports-color - ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -4659,10 +4471,6 @@ snapshots: ast-types-flow@0.0.8: {} - ast-types@0.13.4: - dependencies: - tslib: 2.7.0 - asynckit@0.4.0: {} available-typed-arrays@1.0.7: @@ -4671,14 +4479,6 @@ snapshots: axe-core@4.10.0: {} - axios@1.7.7: - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.1 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - axobject-query@4.1.0: {} babel-jest@29.7.0(@babel/core@7.26.0): @@ -4740,8 +4540,6 @@ snapshots: base64-js@1.5.1: {} - basic-ftp@5.0.5: {} - brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -4766,8 +4564,6 @@ snapshots: dependencies: node-int64: 0.4.0 - buffer-crc32@0.2.13: {} - buffer-from@1.1.2: {} buffer@6.0.3: @@ -4813,19 +4609,6 @@ snapshots: dependencies: readdirp: 4.0.1 - chromedriver@130.0.4: - dependencies: - '@testim/chrome-version': 1.1.4 - axios: 1.7.7 - compare-versions: 6.1.1 - extract-zip: 2.0.1 - proxy-agent: 6.4.0 - proxy-from-env: 1.1.0 - tcp-port-used: 1.0.2 - transitivePeerDependencies: - - debug - - supports-color - ci-info@3.9.0: {} cjs-module-lexer@1.4.1: {} @@ -4866,8 +4649,6 @@ snapshots: dependencies: delayed-stream: 1.0.0 - compare-versions@6.1.1: {} - compute-scroll-into-view@3.1.0: {} concat-map@0.0.1: {} @@ -4919,8 +4700,6 @@ snapshots: damerau-levenshtein@1.0.8: {} - data-uri-to-buffer@6.0.2: {} - data-urls@3.0.2: dependencies: abab: 2.0.6 @@ -4951,10 +4730,6 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.1: - dependencies: - ms: 2.1.2 - debug@4.3.7: dependencies: ms: 2.1.3 @@ -5000,12 +4775,6 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - degenerator@5.0.1: - dependencies: - ast-types: 0.13.4 - escodegen: 2.1.0 - esprima: 4.0.1 - delayed-stream@1.0.0: {} dequal@2.0.3: {} @@ -5042,10 +4811,6 @@ snapshots: emoji-regex@9.2.2: {} - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - enhanced-resolve@5.17.1: dependencies: graceful-fs: 4.2.11 @@ -5415,16 +5180,6 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - extract-zip@2.0.1: - dependencies: - debug: 4.3.7 - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.3 - transitivePeerDependencies: - - supports-color - fast-deep-equal@3.1.3: {} fast-glob@3.3.2: @@ -5447,10 +5202,6 @@ snapshots: dependencies: bser: 2.1.1 - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 @@ -5472,8 +5223,6 @@ snapshots: flatted@3.3.1: {} - follow-redirects@1.15.9: {} - for-each@0.3.3: dependencies: is-callable: 1.2.7 @@ -5489,12 +5238,6 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 - fs-extra@11.2.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -5529,10 +5272,6 @@ snapshots: get-package-type@0.1.0: {} - get-stream@5.2.0: - dependencies: - pump: 3.0.2 - get-stream@6.0.1: {} get-symbol-description@1.0.2: @@ -5545,15 +5284,6 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - get-uri@6.0.3: - dependencies: - basic-ftp: 5.0.5 - data-uri-to-buffer: 6.0.2 - debug: 4.3.7 - fs-extra: 11.2.0 - transitivePeerDependencies: - - supports-color - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -5632,13 +5362,6 @@ snapshots: transitivePeerDependencies: - supports-color - http-proxy-agent@7.0.2: - dependencies: - agent-base: 7.1.1 - debug: 4.3.7 - transitivePeerDependencies: - - supports-color - https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -5646,13 +5369,6 @@ snapshots: transitivePeerDependencies: - supports-color - https-proxy-agent@7.0.5: - dependencies: - agent-base: 7.1.1 - debug: 4.3.7 - transitivePeerDependencies: - - supports-color - human-signals@2.1.0: {} iconv-lite@0.6.3: @@ -5696,13 +5412,6 @@ snapshots: hasown: 2.0.2 side-channel: 1.0.6 - ip-address@9.0.5: - dependencies: - jsbn: 1.1.0 - sprintf-js: 1.1.3 - - ip-regex@4.3.0: {} - is-arguments@1.1.1: dependencies: call-bind: 1.0.7 @@ -5801,8 +5510,6 @@ snapshots: dependencies: which-typed-array: 1.1.15 - is-url@1.2.4: {} - is-weakmap@2.0.2: {} is-weakref@1.0.2: @@ -5814,12 +5521,6 @@ snapshots: call-bind: 1.0.7 get-intrinsic: 1.2.4 - is2@2.0.9: - dependencies: - deep-is: 0.1.4 - ip-regex: 4.3.0 - is-url: 1.2.4 - isarray@1.0.0: {} isarray@2.0.5: {} @@ -6218,8 +5919,6 @@ snapshots: dependencies: argparse: 2.0.1 - jsbn@1.1.0: {} - jsdom@20.0.3: dependencies: abab: 2.0.6 @@ -6273,12 +5972,6 @@ snapshots: json5@2.2.3: {} - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -6342,8 +6035,6 @@ snapshots: dependencies: yallist: 3.1.1 - lru-cache@7.18.3: {} - lz-string@1.5.0: {} make-dir@4.0.0: @@ -6387,16 +6078,12 @@ snapshots: minipass@7.1.2: {} - ms@2.1.2: {} - ms@2.1.3: {} nanoid@3.3.7: {} natural-compare@1.4.0: {} - netmask@2.0.2: {} - next@14.2.13(@babel/core@7.26.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.79.2): dependencies: '@next/env': 14.2.13 @@ -6509,24 +6196,6 @@ snapshots: p-try@2.2.0: {} - pac-proxy-agent@7.0.2: - dependencies: - '@tootallnate/quickjs-emscripten': 0.23.0 - agent-base: 7.1.1 - debug: 4.3.7 - get-uri: 6.0.3 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.5 - pac-resolver: 7.0.1 - socks-proxy-agent: 8.0.4 - transitivePeerDependencies: - - supports-color - - pac-resolver@7.0.1: - dependencies: - degenerator: 5.0.1 - netmask: 2.0.2 - pako@1.0.11: {} parent-module@1.0.1: @@ -6566,8 +6235,6 @@ snapshots: peerjs-js-binarypack: 2.1.0 webrtc-adapter: 9.0.1 - pend@1.2.0: {} - picocolors@1.1.0: {} picomatch@2.3.1: {} @@ -6615,28 +6282,8 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 - proxy-agent@6.4.0: - dependencies: - agent-base: 7.1.1 - debug: 4.3.7 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.5 - lru-cache: 7.18.3 - pac-proxy-agent: 7.0.2 - proxy-from-env: 1.1.0 - socks-proxy-agent: 8.0.4 - transitivePeerDependencies: - - supports-color - - proxy-from-env@1.1.0: {} - psl@1.9.0: {} - pump@3.0.2: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - punycode@2.3.1: {} pure-rand@6.1.0: {} @@ -7178,21 +6825,6 @@ snapshots: slash@3.0.0: {} - smart-buffer@4.2.0: {} - - socks-proxy-agent@8.0.4: - dependencies: - agent-base: 7.1.1 - debug: 4.3.7 - socks: 2.8.3 - transitivePeerDependencies: - - supports-color - - socks@2.8.3: - dependencies: - ip-address: 9.0.5 - smart-buffer: 4.2.0 - source-map-js@1.2.1: {} source-map-support@0.5.13: @@ -7204,8 +6836,6 @@ snapshots: sprintf-js@1.0.3: {} - sprintf-js@1.1.3: {} - stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -7332,13 +6962,6 @@ snapshots: tapable@2.2.1: {} - tcp-port-used@1.0.2: - dependencies: - debug: 4.3.1 - is2: 2.0.9 - transitivePeerDependencies: - - supports-color - test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 @@ -7456,8 +7079,6 @@ snapshots: universalify@0.2.0: {} - universalify@2.0.1: {} - update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: browserslist: 4.24.2 @@ -7622,11 +7243,6 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - yjs@13.6.20: dependencies: lib0: 0.2.98 From f5b521a2f4d26ec5207df63c2e128f4d05551801 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 20:08:03 +0800 Subject: [PATCH 09/35] asd --- .../__tests__/browser-tests/browser.test.ts | 56 ++++++++++++++----- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index a8227c6c77..5d5207c6a8 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -1,23 +1,53 @@ -import { Browser, Builder, By, Key, until } from "selenium-webdriver" +import { Actions, Browser, Builder, By, Key, until, WebDriver } from "selenium-webdriver" import Chrome from "selenium-webdriver/chrome" +const URL = 'http://localhost:3000/'; +const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjk5OTk5OTk5OTk5fQ.Z4_FVGQ5lIcouP3m4YLMr6pGMF17IJFfo2yOTiN58DY" -describe("chrome webdriver installed correctly", () => { - it("does google search", async function test() { - const options = new Chrome.Options().addArguments("--headless=new") as Chrome.Options; - const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); - - const driver = await builder.build(); - - try { +describe("chrome browser", () => { + const options = new Chrome.Options() + // .addArguments("--headless=new") as Chrome.Options; + const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); + let driver: WebDriver; + + beforeEach(async () => { + driver = await builder.build(); + }) + + afterEach(async () => { + await driver.quit(); + }) + + describe.skip("chrome webdriver installed correctly", () => { + it("does google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); - } finally { - await driver.quit(); - } + }); + it("does another google search", async () => { + await driver.get('http://www.google.com'); + await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); + await driver.wait(until.titleIs('webdriver - Google Search'), 1000); + }); }); -}); + + describe("browser-test", () => { + it.skip("accesses and login to peerprep", async () => { + await driver.get(URL); + await driver.wait(until.urlIs(`${URL}login`)); + + const [email, password] = await driver.findElements(By.css("input")) + const submit = await driver.findElement(By.css("button[type=\"submit\"]")) + + await email.sendKeys("admin@gmail.com"); + await password.sendKeys("admin"); + + await submit.click(); + await driver.wait(until.urlIs(`${URL}`)); + }); + }) +}) + From f1e7e40222a3f96cce21e6df3d4596c7f257ee71 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 20:08:35 +0800 Subject: [PATCH 10/35] asd --- apps/frontend/__tests__/browser-tests/browser.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 5d5207c6a8..b3550af901 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -6,7 +6,7 @@ const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3OD describe("chrome browser", () => { const options = new Chrome.Options() - // .addArguments("--headless=new") as Chrome.Options; + .addArguments("--headless=new") as Chrome.Options; const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); let driver: WebDriver; From 45ebeb433a3ca542a98fd90e1ab31092d5bc49f2 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 20:32:04 +0800 Subject: [PATCH 11/35] asd --- .github/workflows/test.yml | 12 +++++++++++- .../frontend/__tests__/browser-tests/browser.test.ts | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dcb13886eb..123a9dd7b3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -112,7 +112,7 @@ jobs: - name: Run tests run: | cd ./apps/frontend - pnpm test -- ./__tests__/browser-tests + pnpm test -- ./__tests__/browser-tests -t "chrome webdriver installed correctly" @@ -253,3 +253,13 @@ jobs: echo "WebSocket for Signalling Service is live" fi # We can add more tests here + + - Name: Install Chrome WebDriver + uses: nanasess/setup-chromedriver@v2 + with: + chromedriver-version: '130.0.6723.116' + + - name: Run Browser Test + run: | + cd ./apps/frontend + pnpm test -- ./__tests__/browser-tests diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index b3550af901..b715255fbd 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -6,7 +6,7 @@ const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3OD describe("chrome browser", () => { const options = new Chrome.Options() - .addArguments("--headless=new") as Chrome.Options; + .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); let driver: WebDriver; @@ -18,7 +18,7 @@ describe("chrome browser", () => { await driver.quit(); }) - describe.skip("chrome webdriver installed correctly", () => { + describe("chrome webdriver installed correctly", () => { it("does google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); From 3570555db6221f063e29670e9110f5b2dda79bb4 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 20:32:56 +0800 Subject: [PATCH 12/35] asd --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 123a9dd7b3..8dfac54250 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -254,7 +254,7 @@ jobs: fi # We can add more tests here - - Name: Install Chrome WebDriver + - name: Install Chrome WebDriver uses: nanasess/setup-chromedriver@v2 with: chromedriver-version: '130.0.6723.116' From cccfa548c8833c97d17d63f833bd73a1781825a4 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 20:44:24 +0800 Subject: [PATCH 13/35] install pnpm --- .github/workflows/test.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8dfac54250..28b1248e66 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -254,6 +254,12 @@ jobs: fi # We can add more tests here + + - name: Install pnpm + - uses: pnpm/action-setup@v4 + with: + version: 9.1.4 + - name: Install Chrome WebDriver uses: nanasess/setup-chromedriver@v2 with: From 2f97a34c78b31c528b9d95cb247281236114f0a5 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 20:45:26 +0800 Subject: [PATCH 14/35] asd --- .github/workflows/test.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 28b1248e66..bd7a397336 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -254,11 +254,10 @@ jobs: fi # We can add more tests here - - name: Install pnpm - - uses: pnpm/action-setup@v4 - with: - version: 9.1.4 + uses: pnpm/action-setup@v4 + with: + version: 9.1.4 - name: Install Chrome WebDriver uses: nanasess/setup-chromedriver@v2 From c78449683241496b903e01b143093f07c42c7e4c Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 21:00:52 +0800 Subject: [PATCH 15/35] asd --- .github/workflows/test.yml | 9 +++++++-- apps/frontend/package.json | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd7a397336..1d8036ba25 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -83,7 +83,7 @@ jobs: - name: Run tests run: | cd ./apps/frontend - pnpm test -- __tests__/unit-tests + pnpm unit-test browser-test: runs-on: ubuntu-latest @@ -259,6 +259,11 @@ jobs: with: version: 9.1.4 + - name: Install dependencies + run: | + cd ./apps/frontend + pnpm i -D + - name: Install Chrome WebDriver uses: nanasess/setup-chromedriver@v2 with: @@ -267,4 +272,4 @@ jobs: - name: Run Browser Test run: | cd ./apps/frontend - pnpm test -- ./__tests__/browser-tests + pnpm browser-test diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 34cedd361d..bab7a93c21 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -7,7 +7,9 @@ "build": "next build", "start": "next start", "lint": "next lint", - "test": "jest" + "test": "jest", + "unit-test": "jest __tests__/unit-tests", + "browser-test": "jest __tests__/browser-tests" }, "dependencies": { "@ant-design/icons": "^5.5.1", From f58f0351a0f83babfcc755ed4b4fc0909ed3cc09 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 21:13:59 +0800 Subject: [PATCH 16/35] asd --- .github/workflows/test.yml | 2 +- apps/frontend/__tests__/browser-tests/browser.test.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1d8036ba25..7b0716889d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -262,7 +262,7 @@ jobs: - name: Install dependencies run: | cd ./apps/frontend - pnpm i -D + pnpm i - name: Install Chrome WebDriver uses: nanasess/setup-chromedriver@v2 diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index b715255fbd..97dcfe8e30 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -6,7 +6,7 @@ const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3OD describe("chrome browser", () => { const options = new Chrome.Options() - .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action + // .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); let driver: WebDriver; @@ -32,7 +32,7 @@ describe("chrome browser", () => { }); describe("browser-test", () => { - it.skip("accesses and login to peerprep", async () => { + it("accesses and login to peerprep", async () => { await driver.get(URL); await driver.wait(until.urlIs(`${URL}login`)); @@ -44,6 +44,11 @@ describe("chrome browser", () => { await submit.click(); await driver.wait(until.urlIs(`${URL}`)); + + const slogan1 = await driver.findElement(By.xpath("/html/body/div[1]/main/div/div[1]/div[2]/span[1]")).then(ele => ele.getText()) + const slogan2 = await driver.findElement(By.xpath("/html/body/div[1]/main/div/div[1]/div[2]/span[2]")).then(ele => ele.getText()) + + expect(slogan1 + slogan2).toBe("A better way to prepare for coding interviews withpeers"); }); }) }) From 862051a6c53d75de3255c07deacaa6ed41156367 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 21:16:04 +0800 Subject: [PATCH 17/35] asd --- .github/workflows/test.yml | 2 +- apps/frontend/__tests__/browser-tests/browser.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7b0716889d..9c2bab3ab7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -112,7 +112,7 @@ jobs: - name: Run tests run: | cd ./apps/frontend - pnpm test -- ./__tests__/browser-tests -t "chrome webdriver installed correctly" + pnpm browser-test -- -t "chrome webdriver installed correctly" diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 97dcfe8e30..1563112b01 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -6,7 +6,7 @@ const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3OD describe("chrome browser", () => { const options = new Chrome.Options() - // .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action + .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); let driver: WebDriver; From 311be82702e8195abba4dc76b3a085e1f72c163d Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Sun, 10 Nov 2024 21:40:29 +0800 Subject: [PATCH 18/35] set up browser tests for Chrome --- .github/workflows/test.yml | 22 ++- .../__tests__/browser-tests/browser.test.ts | 58 ++++++++ .../{ => unit-tests}/Datetime.test.ts | 0 .../dependencymocking.test.ts | 0 .../{ => unit-tests}/question.test.ts | 0 apps/frontend/package.json | 9 +- apps/frontend/pnpm-lock.yaml | 128 ++++++++++++++++++ apps/signalling-service/.dockerignore | 9 ++ apps/signalling-service/pnpm-lock.yaml | 40 +++--- 9 files changed, 247 insertions(+), 19 deletions(-) create mode 100644 apps/frontend/__tests__/browser-tests/browser.test.ts rename apps/frontend/__tests__/{ => unit-tests}/Datetime.test.ts (100%) rename apps/frontend/__tests__/{ => unit-tests}/dependencymocking.test.ts (100%) rename apps/frontend/__tests__/{ => unit-tests}/question.test.ts (100%) create mode 100644 apps/signalling-service/.dockerignore diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 90408360b4..8d18e13b1c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -83,7 +83,7 @@ jobs: - name: Run tests run: | cd ./apps/frontend - pnpm test + pnpm unit-test test-docker-compose: runs-on: ubuntu-latest @@ -222,3 +222,23 @@ jobs: echo "WebSocket for Signalling Service is live" fi # We can add more tests here + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9.1.4 + + - name: Install dependencies + run: | + cd ./apps/frontend + pnpm i + + - name: Install Chrome WebDriver + uses: nanasess/setup-chromedriver@v2 + with: + chromedriver-version: '130.0.6723.116' + + - name: Run Browser Test + run: | + cd ./apps/frontend + pnpm browser-test diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts new file mode 100644 index 0000000000..1563112b01 --- /dev/null +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -0,0 +1,58 @@ +import { Actions, Browser, Builder, By, Key, until, WebDriver } from "selenium-webdriver" + +import Chrome from "selenium-webdriver/chrome" +const URL = 'http://localhost:3000/'; +const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjk5OTk5OTk5OTk5fQ.Z4_FVGQ5lIcouP3m4YLMr6pGMF17IJFfo2yOTiN58DY" + +describe("chrome browser", () => { + const options = new Chrome.Options() + .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action + const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); + let driver: WebDriver; + + beforeEach(async () => { + driver = await builder.build(); + }) + + afterEach(async () => { + await driver.quit(); + }) + + describe("chrome webdriver installed correctly", () => { + it("does google search", async () => { + await driver.get('http://www.google.com'); + await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); + await driver.wait(until.titleIs('webdriver - Google Search'), 1000); + }); + it("does another google search", async () => { + await driver.get('http://www.google.com'); + await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); + await driver.wait(until.titleIs('webdriver - Google Search'), 1000); + }); + }); + + describe("browser-test", () => { + it("accesses and login to peerprep", async () => { + await driver.get(URL); + await driver.wait(until.urlIs(`${URL}login`)); + + const [email, password] = await driver.findElements(By.css("input")) + const submit = await driver.findElement(By.css("button[type=\"submit\"]")) + + await email.sendKeys("admin@gmail.com"); + await password.sendKeys("admin"); + + await submit.click(); + await driver.wait(until.urlIs(`${URL}`)); + + const slogan1 = await driver.findElement(By.xpath("/html/body/div[1]/main/div/div[1]/div[2]/span[1]")).then(ele => ele.getText()) + const slogan2 = await driver.findElement(By.xpath("/html/body/div[1]/main/div/div[1]/div[2]/span[2]")).then(ele => ele.getText()) + + expect(slogan1 + slogan2).toBe("A better way to prepare for coding interviews withpeers"); + }); + }) +}) + + + + diff --git a/apps/frontend/__tests__/Datetime.test.ts b/apps/frontend/__tests__/unit-tests/Datetime.test.ts similarity index 100% rename from apps/frontend/__tests__/Datetime.test.ts rename to apps/frontend/__tests__/unit-tests/Datetime.test.ts diff --git a/apps/frontend/__tests__/dependencymocking.test.ts b/apps/frontend/__tests__/unit-tests/dependencymocking.test.ts similarity index 100% rename from apps/frontend/__tests__/dependencymocking.test.ts rename to apps/frontend/__tests__/unit-tests/dependencymocking.test.ts diff --git a/apps/frontend/__tests__/question.test.ts b/apps/frontend/__tests__/unit-tests/question.test.ts similarity index 100% rename from apps/frontend/__tests__/question.test.ts rename to apps/frontend/__tests__/unit-tests/question.test.ts diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 792fc18474..bab7a93c21 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -7,7 +7,9 @@ "build": "next build", "start": "next start", "lint": "next lint", - "test": "jest" + "test": "jest", + "unit-test": "jest __tests__/unit-tests", + "browser-test": "jest __tests__/browser-tests" }, "dependencies": { "@ant-design/icons": "^5.5.1", @@ -37,19 +39,22 @@ "yjs": "^13.6.20" }, "devDependencies": { - "@types/codemirror": "^5.60.15", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.0.1", + "@types/chromedriver": "^81.0.5", + "@types/codemirror": "^5.60.15", "@types/jest": "^29.5.14", "@types/node": "^20", "@types/peerjs": "^1.1.0", "@types/react": "^18.3.8", "@types/react-dom": "^18.3.0", + "@types/selenium-webdriver": "^4.1.27", "eslint": "^8", "eslint-config-next": "14.2.13", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", + "selenium-webdriver": "^4.26.0", "ts-node": "^10.9.2", "typescript": "^5" }, diff --git a/apps/frontend/pnpm-lock.yaml b/apps/frontend/pnpm-lock.yaml index 413f0c29e3..5b99c479b6 100644 --- a/apps/frontend/pnpm-lock.yaml +++ b/apps/frontend/pnpm-lock.yaml @@ -93,6 +93,9 @@ importers: '@testing-library/react': specifier: ^16.0.1 version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@types/chromedriver': + specifier: ^81.0.5 + version: 81.0.5 '@types/codemirror': specifier: ^5.60.15 version: 5.60.15 @@ -111,6 +114,9 @@ importers: '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 + '@types/selenium-webdriver': + specifier: ^4.1.27 + version: 4.1.27 eslint: specifier: ^8 version: 8.0.0 @@ -123,6 +129,9 @@ importers: jest-environment-jsdom: specifier: ^29.7.0 version: 29.7.0 + selenium-webdriver: + specifier: ^4.26.0 + version: 4.26.0 ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@20.0.0)(typescript@5.0.2) @@ -344,6 +353,9 @@ packages: resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} + '@bazel/runfiles@6.3.1': + resolution: {integrity: sha512-1uLNT5NZsUVIGS4syuHwTzZ8HycMPyr6POA3FCE4GbMtc4rhoJk8aZKtNIRthJYfL+iioppi+rTfH3olMPr9nA==} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -762,6 +774,9 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/chromedriver@81.0.5': + resolution: {integrity: sha512-VwV+WTTFHYZotBn57QQ8gd4TE7CGJ15KPM+xJJrKbiQQSccTY7zVXuConSBlyWrO+AFpVxuzmluK3xvzxGmkCw==} + '@types/codemirror@5.60.15': resolution: {integrity: sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==} @@ -805,6 +820,9 @@ packages: '@types/react@18.3.8': resolution: {integrity: sha512-syBUrW3/XpnW4WJ41Pft+I+aPoDVbrBVQGEnbD7NijDGlVC+8gV/XKRY+7vMDlfPpbwYt0l1vd/Sj8bJGMbs9Q==} + '@types/selenium-webdriver@4.1.27': + resolution: {integrity: sha512-ALqsj8D7Swb6MnBQuAQ58J3KC3yh6fLGtAmpBmnZX8j+0kmP7NaLt56CuzBw2W2bXPrvHFTgn8iekOQFUKXEQA==} + '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} @@ -814,6 +832,9 @@ packages: '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/ws@8.5.13': + resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -1158,6 +1179,9 @@ packages: copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + create-jest@29.7.0: resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1717,6 +1741,9 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + immutable@4.3.7: resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} @@ -1870,6 +1897,9 @@ packages: resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} engines: {node: '>= 0.4'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -2101,6 +2131,9 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + jwt-decode@4.0.0: resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} engines: {node: '>=18'} @@ -2132,6 +2165,9 @@ packages: engines: {node: '>=16'} hasBin: true + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -2319,6 +2355,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2392,6 +2431,9 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -2676,6 +2718,9 @@ packages: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -2756,6 +2801,9 @@ packages: resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -2784,6 +2832,10 @@ packages: sdp@3.2.0: resolution: {integrity: sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==} + selenium-webdriver@4.26.0: + resolution: {integrity: sha512-nA7jMRIPV17mJmAiTDBWN96Sy0Uxrz5CCLb7bLVV6PpL417SyBMPc2Zo/uoREc2EOHlzHwHwAlFtgmSngSY4WQ==} + engines: {node: '>= 14.21.0'} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2801,6 +2853,9 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2892,6 +2947,9 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -2972,6 +3030,10 @@ packages: resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} engines: {node: '>=12.22'} + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -3478,6 +3540,8 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@bazel/runfiles@6.3.1': {} + '@bcoe/v8-coverage@0.2.3': {} '@codemirror/autocomplete@6.18.1(@codemirror/language@6.10.3)(@codemirror/state@6.4.1)(@codemirror/view@6.34.1)(@lezer/common@1.2.3)': @@ -4053,6 +4117,10 @@ snapshots: dependencies: '@babel/types': 7.26.0 + '@types/chromedriver@81.0.5': + dependencies: + '@types/node': 20.0.0 + '@types/codemirror@5.60.15': dependencies: '@types/tern': 0.23.9 @@ -4103,6 +4171,11 @@ snapshots: '@types/prop-types': 15.7.13 csstype: 3.1.3 + '@types/selenium-webdriver@4.1.27': + dependencies: + '@types/node': 20.0.0 + '@types/ws': 8.5.13 + '@types/stack-utils@2.0.3': {} '@types/tern@0.23.9': @@ -4111,6 +4184,10 @@ snapshots: '@types/tough-cookie@4.0.5': {} + '@types/ws@8.5.13': + dependencies: + '@types/node': 20.0.0 + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.33': @@ -4582,6 +4659,8 @@ snapshots: dependencies: toggle-selection: 1.0.6 + core-util-is@1.0.3: {} + create-jest@29.7.0(@types/node@20.0.0)(ts-node@10.9.2(@types/node@20.0.0)(typescript@5.0.2)): dependencies: '@jest/types': 29.6.3 @@ -5302,6 +5381,8 @@ snapshots: ignore@5.3.2: {} + immediate@3.0.6: {} + immutable@4.3.7: {} import-fresh@3.3.0: @@ -5440,6 +5521,8 @@ snapshots: call-bind: 1.0.7 get-intrinsic: 1.2.4 + isarray@1.0.0: {} + isarray@2.0.5: {} isexe@2.0.0: {} @@ -5896,6 +5979,13 @@ snapshots: object.assign: 4.1.5 object.values: 1.2.0 + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + jwt-decode@4.0.0: {} keyv@4.5.4: @@ -5921,6 +6011,10 @@ snapshots: dependencies: isomorphic.js: 0.2.5 + lie@3.3.0: + dependencies: + immediate: 3.0.6 + lines-and-columns@1.2.4: {} locate-path@5.0.0: @@ -6102,6 +6196,8 @@ snapshots: p-try@2.2.0: {} + pako@1.0.11: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -6171,6 +6267,8 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + process-nextick-args@2.0.1: {} + progress@2.0.3: {} prompts@2.4.2: @@ -6539,6 +6637,16 @@ snapshots: dependencies: loose-envify: 1.4.0 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -6620,6 +6728,8 @@ snapshots: has-symbols: 1.0.3 isarray: 2.0.5 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safe-regex-test@1.0.3: @@ -6650,6 +6760,16 @@ snapshots: sdp@3.2.0: {} + selenium-webdriver@4.26.0: + dependencies: + '@bazel/runfiles': 6.3.1 + jszip: 3.10.1 + tmp: 0.2.3 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + semver@6.3.1: {} semver@7.6.3: {} @@ -6670,6 +6790,8 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + setimmediate@1.0.5: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -6787,6 +6909,10 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.0.0 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -6846,6 +6972,8 @@ snapshots: throttle-debounce@5.0.2: {} + tmp@0.2.3: {} + tmpl@1.0.5: {} to-regex-range@5.0.1: diff --git a/apps/signalling-service/.dockerignore b/apps/signalling-service/.dockerignore new file mode 100644 index 0000000000..3f214be645 --- /dev/null +++ b/apps/signalling-service/.dockerignore @@ -0,0 +1,9 @@ +node_modules +.git +.gitignore +README.md +LICENSE +.env +.env* +Dockerfile +.dockerignore \ No newline at end of file diff --git a/apps/signalling-service/pnpm-lock.yaml b/apps/signalling-service/pnpm-lock.yaml index cd6e4916a0..04ce15c614 100644 --- a/apps/signalling-service/pnpm-lock.yaml +++ b/apps/signalling-service/pnpm-lock.yaml @@ -1,32 +1,31 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -dependencies: - lib0: - specifier: ^0.2.98 - version: 0.2.98 - ws: - specifier: ^8.18.0 - version: 8.18.0 +importers: + + .: + dependencies: + lib0: + specifier: ^0.2.98 + version: 0.2.98 + ws: + specifier: ^8.18.0 + version: 8.18.0 packages: - /isomorphic.js@0.2.5: + isomorphic.js@0.2.5: resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} - dev: false - /lib0@0.2.98: + lib0@0.2.98: resolution: {integrity: sha512-XteTiNO0qEXqqweWx+b21p/fBnNHUA1NwAtJNJek1oPrewEZs2uiT4gWivHKr9GqCjDPAhchz0UQO8NwU3bBNA==} engines: {node: '>=16'} hasBin: true - dependencies: - isomorphic.js: 0.2.5 - dev: false - /ws@8.18.0: + ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} peerDependencies: @@ -37,4 +36,13 @@ packages: optional: true utf-8-validate: optional: true - dev: false + +snapshots: + + isomorphic.js@0.2.5: {} + + lib0@0.2.98: + dependencies: + isomorphic.js: 0.2.5 + + ws@8.18.0: {} From f86888bacd25e2770fc6cb0fbfdaab4f728b8272 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Mon, 11 Nov 2024 05:34:02 +0800 Subject: [PATCH 19/35] Increase timeout for browser tests, verbosify jest --- .../frontend/__tests__/browser-tests/browser.test.ts | 9 +++++---- apps/frontend/__tests__/unit-tests/question.test.ts | 12 ++++++------ apps/frontend/package.json | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 1563112b01..22257250c3 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -23,12 +23,12 @@ describe("chrome browser", () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); - }); + }, 10000); it("does another google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); - }); + }, 10000); }); describe("browser-test", () => { @@ -48,8 +48,9 @@ describe("chrome browser", () => { const slogan1 = await driver.findElement(By.xpath("/html/body/div[1]/main/div/div[1]/div[2]/span[1]")).then(ele => ele.getText()) const slogan2 = await driver.findElement(By.xpath("/html/body/div[1]/main/div/div[1]/div[2]/span[2]")).then(ele => ele.getText()) - expect(slogan1 + slogan2).toBe("A better way to prepare for coding interviews withpeers"); - }); + expect(slogan1).toBe("A better way to prepare for coding interviews with"); + expect(slogan2).toBe("peers"); + }, 10000); }) }) diff --git a/apps/frontend/__tests__/unit-tests/question.test.ts b/apps/frontend/__tests__/unit-tests/question.test.ts index 417b4cc7aa..66e22635e3 100644 --- a/apps/frontend/__tests__/unit-tests/question.test.ts +++ b/apps/frontend/__tests__/unit-tests/question.test.ts @@ -126,7 +126,7 @@ describe("GetQuestions", () => { }); - it("gets all questions on the 2nd page with (2) call", async () => { + it("formats (page=2) params correctly", async () => { const res = await GetQuestions(2) @@ -138,7 +138,7 @@ describe("GetQuestions", () => { }]]) }); - it("gets all questions on the 2nd page with (limit=3) call", async () => { + it("formats (limit=3) params correctly", async () => { await GetQuestions(undefined, 3) @@ -150,7 +150,7 @@ describe("GetQuestions", () => { }]]) }); - it("gets all questions on the 2nd page with (limit=3) call", async () => { + it("formats (difficulty asc) params correctly", async () => { await GetQuestions(undefined, undefined, "difficulty asc") @@ -162,7 +162,7 @@ describe("GetQuestions", () => { }]]) }); - it("gets all questions on the 2nd page with (limit=3) call", async () => { + it("formats ([\"easy\", \"hard\"]) params correctly", async () => { await GetQuestions(undefined, undefined, undefined, ["easy", "hard"]) @@ -174,7 +174,7 @@ describe("GetQuestions", () => { }]]) }); - it("formats urls for categories", async () => { + it("formats cat params correctly", async () => { await GetQuestions(undefined, undefined, undefined, undefined, ["CatA", "CatB"]) @@ -189,7 +189,7 @@ describe("GetQuestions", () => { ]]) }); - it("formats url for title", async () => { + it("formats title params correctly", async () => { await GetQuestions(undefined, undefined, undefined, undefined, undefined, "The Title Name") diff --git a/apps/frontend/package.json b/apps/frontend/package.json index bab7a93c21..72690ce9c6 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -8,8 +8,8 @@ "start": "next start", "lint": "next lint", "test": "jest", - "unit-test": "jest __tests__/unit-tests", - "browser-test": "jest __tests__/browser-tests" + "unit-test": "jest --verbose __tests__/unit-tests", + "browser-test": "jest --verbose __tests__/browser-tests" }, "dependencies": { "@ant-design/icons": "^5.5.1", From 96636881de0af527908c2a9b97694940c74ad806 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 14:19:17 +0800 Subject: [PATCH 20/35] asd add browsers --- .github/workflows/test.yml | 8 +++++ .../__tests__/browser-tests/browser.test.ts | 33 ++++++++++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8d18e13b1c..205f1b2af5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -237,6 +237,14 @@ jobs: uses: nanasess/setup-chromedriver@v2 with: chromedriver-version: '130.0.6723.116' + + - name: Install Edge + uses: browser-actions/setup-edge@v1 + with: + edge-version: stable + + - name: Install Geckodriver + uses: browser-actions/setup-geckodriver@latest - name: Run Browser Test run: | diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 22257250c3..a3b44024c9 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -1,14 +1,30 @@ -import { Actions, Browser, Builder, By, Key, until, WebDriver } from "selenium-webdriver" +import { Actions, Browser, Builder, By, Capabilities, Key, until, WebDriver } from "selenium-webdriver" + +import {Options as ChromeOptions} from "selenium-webdriver/chrome" +import {Options as EdgeOptions} from "selenium-webdriver/edge" +import {Options as FirefoxOptions} from "selenium-webdriver/firefox" -import Chrome from "selenium-webdriver/chrome" const URL = 'http://localhost:3000/'; const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjk5OTk5OTk5OTk5fQ.Z4_FVGQ5lIcouP3m4YLMr6pGMF17IJFfo2yOTiN58DY" -describe("chrome browser", () => { - const options = new Chrome.Options() - .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action - const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); +const CHROME_OPTIONS = new ChromeOptions() + .addArguments("--headless=new") as ChromeOptions; // uncomment locally to see the steps in action +const EDGE_OPTIONS = new EdgeOptions() + .addArguments("--headless=new") as EdgeOptions; +const FIREFOX_OPTIONS = new FirefoxOptions() + .addArguments("--headless") as FirefoxOptions; + +const builder = new Builder() + .setChromeOptions(CHROME_OPTIONS) + .setEdgeOptions(EDGE_OPTIONS) + .setFirefoxOptions(FIREFOX_OPTIONS) + +describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", (browser) => { let driver: WebDriver; + beforeAll(() => { + const cap = new Capabilities().setBrowserName(browser) + builder.withCapabilities(cap); + }) beforeEach(async () => { driver = await builder.build(); @@ -18,13 +34,14 @@ describe("chrome browser", () => { await driver.quit(); }) - describe("chrome webdriver installed correctly", () => { + describe.skip("webdriver installed correctly", () => { it("does google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); }, 10000); - it("does another google search", async () => { + + it.skip("does another google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); From 3a975ffd4232f436bc9c817df17cd7312086e66f Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 14:37:56 +0800 Subject: [PATCH 21/35] asd --- .github/workflows/test.yml | 37 +++++++++++++++++++ .../__tests__/browser-tests/browser.test.ts | 5 ++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 205f1b2af5..4a63c918a2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -85,6 +85,43 @@ jobs: cd ./apps/frontend pnpm unit-test + + test-webdriver-working: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9.1.4 + + - name: Install dependencies + run: | + cd ./apps/frontend + pnpm i + + - name: Install Chrome WebDriver + uses: nanasess/setup-chromedriver@v2 + with: + chromedriver-version: '130.0.6723.116' + + - name: Install Edge + uses: browser-actions/setup-edge@v1 + with: + edge-version: stable + + - name: Install Geckodriver + uses: browser-actions/setup-geckodriver@latest + + + - name: Run Browser Test + run: | + cd ./apps/frontend + pnpm browser-test -- -t "webdriver installed correctly" + test-docker-compose: runs-on: ubuntu-latest diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index a3b44024c9..bc19217b25 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -10,8 +10,11 @@ const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3OD const CHROME_OPTIONS = new ChromeOptions() .addArguments("--headless=new") as ChromeOptions; // uncomment locally to see the steps in action const EDGE_OPTIONS = new EdgeOptions() + .setBinaryPath("/opt/hostedtoolcache/msedge/stable/x64/msedge") .addArguments("--headless=new") as EdgeOptions; + const FIREFOX_OPTIONS = new FirefoxOptions() + .setBinary("/opt/hostedtoolcache/geckodriver/0.35.0/x64/geckodriver") .addArguments("--headless") as FirefoxOptions; const builder = new Builder() @@ -34,7 +37,7 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", await driver.quit(); }) - describe.skip("webdriver installed correctly", () => { + describe("webdriver installed correctly", () => { it("does google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); From e92e18608afc9a882da7568bfffbe0b96cf01146 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 14:47:29 +0800 Subject: [PATCH 22/35] asd --- .github/workflows/test.yml | 321 ++++++++++++++++++------------------- 1 file changed, 160 insertions(+), 161 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4a63c918a2..1be8c49c8c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -85,7 +85,6 @@ jobs: cd ./apps/frontend pnpm unit-test - test-webdriver-working: runs-on: ubuntu-latest @@ -120,170 +119,170 @@ jobs: - name: Run Browser Test run: | cd ./apps/frontend - pnpm browser-test -- -t "webdriver installed correctly" - - test-docker-compose: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Docker Compose - run: | - sudo apt-get update - sudo apt-get install -y docker-compose - - - name: Create Environment Files - env: - QUESTION_SERVICE_URL: ${{ vars.QUESTION_SERVICE_URL }} - USER_SERVICE_URL: ${{ vars.USER_SERVICE_URL }} - MATCHING_SERVICE_URL: ${{ vars.MATCHING_SERVICE_URL }} - HISTORY_SERVICE_URL: ${{ vars.HISTORY_SERVICE_URL }} - SIGNALLING_SERVICE_URL: ${{ vars.SIGNALLING_SERVICE_URL }} - EXECUTION_SERVICE_URL: ${{ vars.EXECUTION_SERVICE_URL }} - JWT_SECRET: ${{ secrets.JWT_SECRET }} - QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} - HISTORY_FIREBASE_CREDENTIAL_PATH: ${{ vars.HISTORY_SERVICE_FIREBASE_CREDENTIAL_PATH }} - EXECUTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.EXECUTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} - DB_CLOUD_URI: ${{ secrets.USER_SERVICE_DB_CLOUD_URI }} - USER_SERVICE_PORT: ${{ vars.USER_SERVICE_PORT }} - MATCHING_SERVICE_PORT: ${{ vars.MATCHING_SERVICE_PORT }} - HISTORY_SERVICE_PORT: ${{ vars.HISTORY_SERVICE_PORT }} - SIGNALLING_SERVICE_PORT: ${{ vars.SIGNALLING_SERVICE_PORT }} - EXECUTION_SERVICE_PORT: ${{ vars.EXECUTION_SERVICE_PORT }} - MATCHING_SERVICE_TIMEOUT: ${{ vars.MATCHING_SERVICE_TIMEOUT }} - REDIS_URL: ${{ vars.REDIS_URL }} - QUESTION_SERVICE_GRPC_URL: ${{ vars.QUESTION_SERVICE_GPRC_URL }} - run: | - cd ./apps/frontend - echo "NEXT_PUBLIC_QUESTION_SERVICE_URL=$QUESTION_SERVICE_URL" >> .env - echo "NEXT_PUBLIC_USER_SERVICE_URL=$USER_SERVICE_URL" >> .env - echo "NEXT_PUBLIC_MATCHING_SERVICE_URL=$MATCHING_SERVICE_URL" >> .env - echo "NEXT_PUBLIC_HISTORY_SERVICE_URL=$HISTORY_SERVICE_URL" >> .env - echo "NEXT_PUBLIC_SIGNALLING_SERVICE_URL=$SIGNALLING_SERVICE_URL" >> .env - echo "NEXT_PUBLIC_EXECUTION_SERVICE_URL=EXECUTION_SERVICE_URL" >> .env - - cd ../question-service - echo "FIREBASE_CREDENTIAL_PATH=$QUESTION_FIREBASE_CREDENTIAL_PATH" >> .env - echo "JWT_SECRET=$JWT_SECRET" >> .env - echo "EXECUTION_SERVICE_URL=$EXECUTION_SERVICE_URL" >> .env - - cd ../user-service - echo "DB_CLOUD_URI=$DB_CLOUD_URI" >> .env - echo "PORT=$USER_SERVICE_PORT" >> .env - echo "JWT_SECRET=$JWT_SECRET" >> .env - - cd ../matching-service - echo "PORT=$MATCHING_SERVICE_PORT" >> .env - echo "MATCH_TIMEOUT=$MATCHING_SERVICE_TIMEOUT" >> .env - echo "JWT_SECRET=$JWT_SECRET" >> .env - echo "REDIS_URL=$REDIS_URL" >> .env - echo "QUESTION_SERVICE_GRPC_URL=$QUESTION_SERVICE_GRPC_URL" >> .env - - cd ../history-service - echo "FIREBASE_CREDENTIAL_PATH=$HISTORY_FIREBASE_CREDENTIAL_PATH" >> .env - echo "PORT=$HISTORY_SERVICE_PORT" >> .env + pnpm browser-test -t "webdriver installed correctly" + + # test-docker-compose: + # runs-on: ubuntu-latest + + # steps: + # - name: Checkout code + # uses: actions/checkout@v4 + + # - name: Set up Docker Compose + # run: | + # sudo apt-get update + # sudo apt-get install -y docker-compose + + # - name: Create Environment Files + # env: + # QUESTION_SERVICE_URL: ${{ vars.QUESTION_SERVICE_URL }} + # USER_SERVICE_URL: ${{ vars.USER_SERVICE_URL }} + # MATCHING_SERVICE_URL: ${{ vars.MATCHING_SERVICE_URL }} + # HISTORY_SERVICE_URL: ${{ vars.HISTORY_SERVICE_URL }} + # SIGNALLING_SERVICE_URL: ${{ vars.SIGNALLING_SERVICE_URL }} + # EXECUTION_SERVICE_URL: ${{ vars.EXECUTION_SERVICE_URL }} + # JWT_SECRET: ${{ secrets.JWT_SECRET }} + # QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} + # HISTORY_FIREBASE_CREDENTIAL_PATH: ${{ vars.HISTORY_SERVICE_FIREBASE_CREDENTIAL_PATH }} + # EXECUTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.EXECUTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} + # DB_CLOUD_URI: ${{ secrets.USER_SERVICE_DB_CLOUD_URI }} + # USER_SERVICE_PORT: ${{ vars.USER_SERVICE_PORT }} + # MATCHING_SERVICE_PORT: ${{ vars.MATCHING_SERVICE_PORT }} + # HISTORY_SERVICE_PORT: ${{ vars.HISTORY_SERVICE_PORT }} + # SIGNALLING_SERVICE_PORT: ${{ vars.SIGNALLING_SERVICE_PORT }} + # EXECUTION_SERVICE_PORT: ${{ vars.EXECUTION_SERVICE_PORT }} + # MATCHING_SERVICE_TIMEOUT: ${{ vars.MATCHING_SERVICE_TIMEOUT }} + # REDIS_URL: ${{ vars.REDIS_URL }} + # QUESTION_SERVICE_GRPC_URL: ${{ vars.QUESTION_SERVICE_GPRC_URL }} + # run: | + # cd ./apps/frontend + # echo "NEXT_PUBLIC_QUESTION_SERVICE_URL=$QUESTION_SERVICE_URL" >> .env + # echo "NEXT_PUBLIC_USER_SERVICE_URL=$USER_SERVICE_URL" >> .env + # echo "NEXT_PUBLIC_MATCHING_SERVICE_URL=$MATCHING_SERVICE_URL" >> .env + # echo "NEXT_PUBLIC_HISTORY_SERVICE_URL=$HISTORY_SERVICE_URL" >> .env + # echo "NEXT_PUBLIC_SIGNALLING_SERVICE_URL=$SIGNALLING_SERVICE_URL" >> .env + # echo "NEXT_PUBLIC_EXECUTION_SERVICE_URL=EXECUTION_SERVICE_URL" >> .env + + # cd ../question-service + # echo "FIREBASE_CREDENTIAL_PATH=$QUESTION_FIREBASE_CREDENTIAL_PATH" >> .env + # echo "JWT_SECRET=$JWT_SECRET" >> .env + # echo "EXECUTION_SERVICE_URL=$EXECUTION_SERVICE_URL" >> .env + + # cd ../user-service + # echo "DB_CLOUD_URI=$DB_CLOUD_URI" >> .env + # echo "PORT=$USER_SERVICE_PORT" >> .env + # echo "JWT_SECRET=$JWT_SECRET" >> .env + + # cd ../matching-service + # echo "PORT=$MATCHING_SERVICE_PORT" >> .env + # echo "MATCH_TIMEOUT=$MATCHING_SERVICE_TIMEOUT" >> .env + # echo "JWT_SECRET=$JWT_SECRET" >> .env + # echo "REDIS_URL=$REDIS_URL" >> .env + # echo "QUESTION_SERVICE_GRPC_URL=$QUESTION_SERVICE_GRPC_URL" >> .env + + # cd ../history-service + # echo "FIREBASE_CREDENTIAL_PATH=$HISTORY_FIREBASE_CREDENTIAL_PATH" >> .env + # echo "PORT=$HISTORY_SERVICE_PORT" >> .env - cd ../execution-service - echo "FIREBASE_CREDENTIAL_PATH=$EXECUTION_FIREBASE_CREDENTIAL_PATH" >> .env - echo "PORT=$EXECUTION_SERVICE_PORT" >> .env - echo "HISTORY_SERVICE_URL=$HISTORY_SERVICE_URL" >> .env - - cd ../signalling-service - echo "PORT=$SIGNALLING_SERVICE_PORT" >> .env - - - name: Create Database Credential Files - env: - QUESTION_FIREBASE_JSON: ${{ secrets.QUESTION_SERVICE_FIREBASE_CREDENTIAL }} - QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} - HISTORY_FIREBASE_JSON: ${{ secrets.HISTORY_SERVICE_FIREBASE_CREDENTIAL }} - HISTORY_FIREBASE_CREDENTIAL_PATH: ${{ vars.HISTORY_SERVICE_FIREBASE_CREDENTIAL_PATH }} - EXECUTION_FIREBASE_JSON: ${{ secrets.EXECUTION_SERVICE_FIREBASE_CREDENTIAL }} - EXECUTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.EXECUTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} - run: | - cd ./apps/question-service - echo "$QUESTION_FIREBASE_JSON" > "./$QUESTION_FIREBASE_CREDENTIAL_PATH" - - cd ../history-service - echo "$HISTORY_FIREBASE_JSON" > "./$HISTORY_FIREBASE_CREDENTIAL_PATH" + # cd ../execution-service + # echo "FIREBASE_CREDENTIAL_PATH=$EXECUTION_FIREBASE_CREDENTIAL_PATH" >> .env + # echo "PORT=$EXECUTION_SERVICE_PORT" >> .env + # echo "HISTORY_SERVICE_URL=$HISTORY_SERVICE_URL" >> .env + + # cd ../signalling-service + # echo "PORT=$SIGNALLING_SERVICE_PORT" >> .env + + # - name: Create Database Credential Files + # env: + # QUESTION_FIREBASE_JSON: ${{ secrets.QUESTION_SERVICE_FIREBASE_CREDENTIAL }} + # QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} + # HISTORY_FIREBASE_JSON: ${{ secrets.HISTORY_SERVICE_FIREBASE_CREDENTIAL }} + # HISTORY_FIREBASE_CREDENTIAL_PATH: ${{ vars.HISTORY_SERVICE_FIREBASE_CREDENTIAL_PATH }} + # EXECUTION_FIREBASE_JSON: ${{ secrets.EXECUTION_SERVICE_FIREBASE_CREDENTIAL }} + # EXECUTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.EXECUTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} + # run: | + # cd ./apps/question-service + # echo "$QUESTION_FIREBASE_JSON" > "./$QUESTION_FIREBASE_CREDENTIAL_PATH" + + # cd ../history-service + # echo "$HISTORY_FIREBASE_JSON" > "./$HISTORY_FIREBASE_CREDENTIAL_PATH" - cd ../execution-service - echo "$EXECUTION_FIREBASE_JSON" > "./$EXECUTION_FIREBASE_CREDENTIAL_PATH" - - - name: Build and Run Services - run: | - cd ./apps - docker-compose up --build -d - - - name: Wait for services to be ready - run: sleep 30 - - - name: Install websocat - run: | - sudo wget -qO /usr/local/bin/websocat https://github.com/vi/websocat/releases/latest/download/websocat.x86_64-unknown-linux-musl - sudo chmod a+x /usr/local/bin/websocat - websocat --version - - - name: Run Tests - env: - FRONTEND_URL: ${{ vars.FRONTEND_URL }} - USER_SERVICE_URL: ${{ vars.USER_SERVICE_URL }} - QUESTION_SERVICE_URL: ${{ vars.QUESTION_SERVICE_URL }} - MATCHING_SERVICE_URL: ${{ vars.MATCHING_SERVICE_URL }} - HISTORY_SERVICE_URL: ${{ vars.HISTORY_SERVICE_URL }} - SIGNALLING_SERVICE_URL: ${{ vars.SIGNALLING_SERVICE_URL }} - EXECUTION_SERVICE_URL: ${{ vars.EXECUTION_SERVICE_URL }} - run: | - echo "Testing Question Service..." - curl -sSL -o /dev/null $QUESTION_SERVICE_URL && echo "Question Service is up" - echo "Testing User Service..." - curl -fsSL -o /dev/null $USER_SERVICE_URL && echo "User Service is up" - echo "Testing Frontend..." - curl -fsSL -o /dev/null $FRONTEND_URL && echo "Frontend is up" - echo "Testing History Service..." - curl -fsSL -o /dev/null $HISTORY_SERVICE_URL && echo "History Service is up" - echo "Testing Execution Service..." - curl -fsSL -o /dev/null $EXECUTION_SERVICE_URL && echo "Execution Service is up" - echo "Testing Matching Service..." - if ! (echo "Hello" | websocat $MATCHING_SERVICE_URL); then - echo "WebSocket for Matching Service is not live" - else - echo "WebSocket for Matching Service is live" - fi - # Add in test for matching service in the future - echo "Testing Signalling Service..." - if ! (echo "Hello" | websocat $SIGNALLING_SERVICE_URL); then - echo "WebSocket for Signalling Service is not live" - else - echo "WebSocket for Signalling Service is live" - fi - # We can add more tests here + # cd ../execution-service + # echo "$EXECUTION_FIREBASE_JSON" > "./$EXECUTION_FIREBASE_CREDENTIAL_PATH" + + # - name: Build and Run Services + # run: | + # cd ./apps + # docker-compose up --build -d + + # - name: Wait for services to be ready + # run: sleep 30 + + # - name: Install websocat + # run: | + # sudo wget -qO /usr/local/bin/websocat https://github.com/vi/websocat/releases/latest/download/websocat.x86_64-unknown-linux-musl + # sudo chmod a+x /usr/local/bin/websocat + # websocat --version + + # - name: Run Tests + # env: + # FRONTEND_URL: ${{ vars.FRONTEND_URL }} + # USER_SERVICE_URL: ${{ vars.USER_SERVICE_URL }} + # QUESTION_SERVICE_URL: ${{ vars.QUESTION_SERVICE_URL }} + # MATCHING_SERVICE_URL: ${{ vars.MATCHING_SERVICE_URL }} + # HISTORY_SERVICE_URL: ${{ vars.HISTORY_SERVICE_URL }} + # SIGNALLING_SERVICE_URL: ${{ vars.SIGNALLING_SERVICE_URL }} + # EXECUTION_SERVICE_URL: ${{ vars.EXECUTION_SERVICE_URL }} + # run: | + # echo "Testing Question Service..." + # curl -sSL -o /dev/null $QUESTION_SERVICE_URL && echo "Question Service is up" + # echo "Testing User Service..." + # curl -fsSL -o /dev/null $USER_SERVICE_URL && echo "User Service is up" + # echo "Testing Frontend..." + # curl -fsSL -o /dev/null $FRONTEND_URL && echo "Frontend is up" + # echo "Testing History Service..." + # curl -fsSL -o /dev/null $HISTORY_SERVICE_URL && echo "History Service is up" + # echo "Testing Execution Service..." + # curl -fsSL -o /dev/null $EXECUTION_SERVICE_URL && echo "Execution Service is up" + # echo "Testing Matching Service..." + # if ! (echo "Hello" | websocat $MATCHING_SERVICE_URL); then + # echo "WebSocket for Matching Service is not live" + # else + # echo "WebSocket for Matching Service is live" + # fi + # # Add in test for matching service in the future + # echo "Testing Signalling Service..." + # if ! (echo "Hello" | websocat $SIGNALLING_SERVICE_URL); then + # echo "WebSocket for Signalling Service is not live" + # else + # echo "WebSocket for Signalling Service is live" + # fi + # # We can add more tests here - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 9.1.4 - - - name: Install dependencies - run: | - cd ./apps/frontend - pnpm i + # - name: Install pnpm + # uses: pnpm/action-setup@v4 + # with: + # version: 9.1.4 + + # - name: Install dependencies + # run: | + # cd ./apps/frontend + # pnpm i - - name: Install Chrome WebDriver - uses: nanasess/setup-chromedriver@v2 - with: - chromedriver-version: '130.0.6723.116' + # - name: Install Chrome WebDriver + # uses: nanasess/setup-chromedriver@v2 + # with: + # chromedriver-version: '130.0.6723.116' - - name: Install Edge - uses: browser-actions/setup-edge@v1 - with: - edge-version: stable + # - name: Install Edge + # uses: browser-actions/setup-edge@v1 + # with: + # edge-version: stable - - name: Install Geckodriver - uses: browser-actions/setup-geckodriver@latest + # - name: Install Geckodriver + # uses: browser-actions/setup-geckodriver@latest - - name: Run Browser Test - run: | - cd ./apps/frontend - pnpm browser-test + # - name: Run Browser Test + # run: | + # cd ./apps/frontend + # pnpm browser-test From e400a7176baaa4e272963760be97de84c9bf943a Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 14:53:23 +0800 Subject: [PATCH 23/35] asd --- .github/workflows/test.yml | 165 ------------------------------------- 1 file changed, 165 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1be8c49c8c..530eb00e7f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -121,168 +121,3 @@ jobs: cd ./apps/frontend pnpm browser-test -t "webdriver installed correctly" - # test-docker-compose: - # runs-on: ubuntu-latest - - # steps: - # - name: Checkout code - # uses: actions/checkout@v4 - - # - name: Set up Docker Compose - # run: | - # sudo apt-get update - # sudo apt-get install -y docker-compose - - # - name: Create Environment Files - # env: - # QUESTION_SERVICE_URL: ${{ vars.QUESTION_SERVICE_URL }} - # USER_SERVICE_URL: ${{ vars.USER_SERVICE_URL }} - # MATCHING_SERVICE_URL: ${{ vars.MATCHING_SERVICE_URL }} - # HISTORY_SERVICE_URL: ${{ vars.HISTORY_SERVICE_URL }} - # SIGNALLING_SERVICE_URL: ${{ vars.SIGNALLING_SERVICE_URL }} - # EXECUTION_SERVICE_URL: ${{ vars.EXECUTION_SERVICE_URL }} - # JWT_SECRET: ${{ secrets.JWT_SECRET }} - # QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} - # HISTORY_FIREBASE_CREDENTIAL_PATH: ${{ vars.HISTORY_SERVICE_FIREBASE_CREDENTIAL_PATH }} - # EXECUTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.EXECUTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} - # DB_CLOUD_URI: ${{ secrets.USER_SERVICE_DB_CLOUD_URI }} - # USER_SERVICE_PORT: ${{ vars.USER_SERVICE_PORT }} - # MATCHING_SERVICE_PORT: ${{ vars.MATCHING_SERVICE_PORT }} - # HISTORY_SERVICE_PORT: ${{ vars.HISTORY_SERVICE_PORT }} - # SIGNALLING_SERVICE_PORT: ${{ vars.SIGNALLING_SERVICE_PORT }} - # EXECUTION_SERVICE_PORT: ${{ vars.EXECUTION_SERVICE_PORT }} - # MATCHING_SERVICE_TIMEOUT: ${{ vars.MATCHING_SERVICE_TIMEOUT }} - # REDIS_URL: ${{ vars.REDIS_URL }} - # QUESTION_SERVICE_GRPC_URL: ${{ vars.QUESTION_SERVICE_GPRC_URL }} - # run: | - # cd ./apps/frontend - # echo "NEXT_PUBLIC_QUESTION_SERVICE_URL=$QUESTION_SERVICE_URL" >> .env - # echo "NEXT_PUBLIC_USER_SERVICE_URL=$USER_SERVICE_URL" >> .env - # echo "NEXT_PUBLIC_MATCHING_SERVICE_URL=$MATCHING_SERVICE_URL" >> .env - # echo "NEXT_PUBLIC_HISTORY_SERVICE_URL=$HISTORY_SERVICE_URL" >> .env - # echo "NEXT_PUBLIC_SIGNALLING_SERVICE_URL=$SIGNALLING_SERVICE_URL" >> .env - # echo "NEXT_PUBLIC_EXECUTION_SERVICE_URL=EXECUTION_SERVICE_URL" >> .env - - # cd ../question-service - # echo "FIREBASE_CREDENTIAL_PATH=$QUESTION_FIREBASE_CREDENTIAL_PATH" >> .env - # echo "JWT_SECRET=$JWT_SECRET" >> .env - # echo "EXECUTION_SERVICE_URL=$EXECUTION_SERVICE_URL" >> .env - - # cd ../user-service - # echo "DB_CLOUD_URI=$DB_CLOUD_URI" >> .env - # echo "PORT=$USER_SERVICE_PORT" >> .env - # echo "JWT_SECRET=$JWT_SECRET" >> .env - - # cd ../matching-service - # echo "PORT=$MATCHING_SERVICE_PORT" >> .env - # echo "MATCH_TIMEOUT=$MATCHING_SERVICE_TIMEOUT" >> .env - # echo "JWT_SECRET=$JWT_SECRET" >> .env - # echo "REDIS_URL=$REDIS_URL" >> .env - # echo "QUESTION_SERVICE_GRPC_URL=$QUESTION_SERVICE_GRPC_URL" >> .env - - # cd ../history-service - # echo "FIREBASE_CREDENTIAL_PATH=$HISTORY_FIREBASE_CREDENTIAL_PATH" >> .env - # echo "PORT=$HISTORY_SERVICE_PORT" >> .env - - # cd ../execution-service - # echo "FIREBASE_CREDENTIAL_PATH=$EXECUTION_FIREBASE_CREDENTIAL_PATH" >> .env - # echo "PORT=$EXECUTION_SERVICE_PORT" >> .env - # echo "HISTORY_SERVICE_URL=$HISTORY_SERVICE_URL" >> .env - - # cd ../signalling-service - # echo "PORT=$SIGNALLING_SERVICE_PORT" >> .env - - # - name: Create Database Credential Files - # env: - # QUESTION_FIREBASE_JSON: ${{ secrets.QUESTION_SERVICE_FIREBASE_CREDENTIAL }} - # QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} - # HISTORY_FIREBASE_JSON: ${{ secrets.HISTORY_SERVICE_FIREBASE_CREDENTIAL }} - # HISTORY_FIREBASE_CREDENTIAL_PATH: ${{ vars.HISTORY_SERVICE_FIREBASE_CREDENTIAL_PATH }} - # EXECUTION_FIREBASE_JSON: ${{ secrets.EXECUTION_SERVICE_FIREBASE_CREDENTIAL }} - # EXECUTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.EXECUTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} - # run: | - # cd ./apps/question-service - # echo "$QUESTION_FIREBASE_JSON" > "./$QUESTION_FIREBASE_CREDENTIAL_PATH" - - # cd ../history-service - # echo "$HISTORY_FIREBASE_JSON" > "./$HISTORY_FIREBASE_CREDENTIAL_PATH" - - # cd ../execution-service - # echo "$EXECUTION_FIREBASE_JSON" > "./$EXECUTION_FIREBASE_CREDENTIAL_PATH" - - # - name: Build and Run Services - # run: | - # cd ./apps - # docker-compose up --build -d - - # - name: Wait for services to be ready - # run: sleep 30 - - # - name: Install websocat - # run: | - # sudo wget -qO /usr/local/bin/websocat https://github.com/vi/websocat/releases/latest/download/websocat.x86_64-unknown-linux-musl - # sudo chmod a+x /usr/local/bin/websocat - # websocat --version - - # - name: Run Tests - # env: - # FRONTEND_URL: ${{ vars.FRONTEND_URL }} - # USER_SERVICE_URL: ${{ vars.USER_SERVICE_URL }} - # QUESTION_SERVICE_URL: ${{ vars.QUESTION_SERVICE_URL }} - # MATCHING_SERVICE_URL: ${{ vars.MATCHING_SERVICE_URL }} - # HISTORY_SERVICE_URL: ${{ vars.HISTORY_SERVICE_URL }} - # SIGNALLING_SERVICE_URL: ${{ vars.SIGNALLING_SERVICE_URL }} - # EXECUTION_SERVICE_URL: ${{ vars.EXECUTION_SERVICE_URL }} - # run: | - # echo "Testing Question Service..." - # curl -sSL -o /dev/null $QUESTION_SERVICE_URL && echo "Question Service is up" - # echo "Testing User Service..." - # curl -fsSL -o /dev/null $USER_SERVICE_URL && echo "User Service is up" - # echo "Testing Frontend..." - # curl -fsSL -o /dev/null $FRONTEND_URL && echo "Frontend is up" - # echo "Testing History Service..." - # curl -fsSL -o /dev/null $HISTORY_SERVICE_URL && echo "History Service is up" - # echo "Testing Execution Service..." - # curl -fsSL -o /dev/null $EXECUTION_SERVICE_URL && echo "Execution Service is up" - # echo "Testing Matching Service..." - # if ! (echo "Hello" | websocat $MATCHING_SERVICE_URL); then - # echo "WebSocket for Matching Service is not live" - # else - # echo "WebSocket for Matching Service is live" - # fi - # # Add in test for matching service in the future - # echo "Testing Signalling Service..." - # if ! (echo "Hello" | websocat $SIGNALLING_SERVICE_URL); then - # echo "WebSocket for Signalling Service is not live" - # else - # echo "WebSocket for Signalling Service is live" - # fi - # # We can add more tests here - - # - name: Install pnpm - # uses: pnpm/action-setup@v4 - # with: - # version: 9.1.4 - - # - name: Install dependencies - # run: | - # cd ./apps/frontend - # pnpm i - - # - name: Install Chrome WebDriver - # uses: nanasess/setup-chromedriver@v2 - # with: - # chromedriver-version: '130.0.6723.116' - - # - name: Install Edge - # uses: browser-actions/setup-edge@v1 - # with: - # edge-version: stable - - # - name: Install Geckodriver - # uses: browser-actions/setup-geckodriver@latest - - # - name: Run Browser Test - # run: | - # cd ./apps/frontend - # pnpm browser-test From 4c405f4abeea7037ee8e00793d304fd0cc852b04 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 14:57:22 +0800 Subject: [PATCH 24/35] asd --- apps/frontend/__tests__/browser-tests/browser.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index bc19217b25..51b36aec2d 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -27,9 +27,11 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", beforeAll(() => { const cap = new Capabilities().setBrowserName(browser) builder.withCapabilities(cap); + console.log("got here"); }) beforeEach(async () => { + console.log("got here"); driver = await builder.build(); }) @@ -39,6 +41,7 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", describe("webdriver installed correctly", () => { it("does google search", async () => { + console.log("got here"); await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); @@ -51,7 +54,7 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", }, 10000); }); - describe("browser-test", () => { + describe.skip("browser-test", () => { it("accesses and login to peerprep", async () => { await driver.get(URL); await driver.wait(until.urlIs(`${URL}login`)); From 64e2651e87df7f34a684b2fadba6b5f2b8a1a0b0 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 15:00:01 +0800 Subject: [PATCH 25/35] asd --- apps/frontend/__tests__/browser-tests/browser.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 51b36aec2d..fe93068c29 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -27,11 +27,9 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", beforeAll(() => { const cap = new Capabilities().setBrowserName(browser) builder.withCapabilities(cap); - console.log("got here"); }) beforeEach(async () => { - console.log("got here"); driver = await builder.build(); }) @@ -41,10 +39,12 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", describe("webdriver installed correctly", () => { it("does google search", async () => { - console.log("got here"); + console.log("getting url"); await driver.get('http://www.google.com'); + console.log("got url"); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); + console.log("did search"); }, 10000); it.skip("does another google search", async () => { From 3657a9c493956ca91a3a6f40ecb624c0c1e7edf4 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 15:05:03 +0800 Subject: [PATCH 26/35] asd --- apps/frontend/__tests__/browser-tests/browser.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index fe93068c29..8715fb7a10 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -30,7 +30,9 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", }) beforeEach(async () => { + console.log(browser + ": building..."); driver = await builder.build(); + console.log(browser + ": built"); }) afterEach(async () => { From 75559763d8bba422279f725250eab82bcd8e29e0 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 15:07:33 +0800 Subject: [PATCH 27/35] asd --- apps/frontend/__tests__/browser-tests/browser.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 8715fb7a10..32e108a755 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -14,7 +14,7 @@ const EDGE_OPTIONS = new EdgeOptions() .addArguments("--headless=new") as EdgeOptions; const FIREFOX_OPTIONS = new FirefoxOptions() - .setBinary("/opt/hostedtoolcache/geckodriver/0.35.0/x64/geckodriver") + .setBinary("/opt/hostedfasdjhflkajsdlkjfhalsdj") .addArguments("--headless") as FirefoxOptions; const builder = new Builder() From d3eb518711444100d107b53dff555735a18a5cc4 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 15:21:42 +0800 Subject: [PATCH 28/35] asd --- apps/frontend/__tests__/browser-tests/browser.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 32e108a755..de5af9335a 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -14,7 +14,7 @@ const EDGE_OPTIONS = new EdgeOptions() .addArguments("--headless=new") as EdgeOptions; const FIREFOX_OPTIONS = new FirefoxOptions() - .setBinary("/opt/hostedfasdjhflkajsdlkjfhalsdj") + // .setBinary("/opt/hostedtoolcache/geckodriver/0.35.0/x64/geckodriver") .addArguments("--headless") as FirefoxOptions; const builder = new Builder() From e0c62de5608652a6ad501119c3e74cecbf23b1c8 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 15:23:44 +0800 Subject: [PATCH 29/35] asd --- apps/frontend/__tests__/browser-tests/browser.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index de5af9335a..20b49ba1bd 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -10,11 +10,10 @@ const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3OD const CHROME_OPTIONS = new ChromeOptions() .addArguments("--headless=new") as ChromeOptions; // uncomment locally to see the steps in action const EDGE_OPTIONS = new EdgeOptions() - .setBinaryPath("/opt/hostedtoolcache/msedge/stable/x64/msedge") + .setBinaryPath("/opt/hostedtoolcache/msedge/stable/x64/msedge") // need to point to the correct path .addArguments("--headless=new") as EdgeOptions; const FIREFOX_OPTIONS = new FirefoxOptions() - // .setBinary("/opt/hostedtoolcache/geckodriver/0.35.0/x64/geckodriver") .addArguments("--headless") as FirefoxOptions; const builder = new Builder() From 266971d9fb642ca5dfc8692cb427720b8f2cb188 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 15:26:30 +0800 Subject: [PATCH 30/35] Squashed commit of the following: commit e0c62de5608652a6ad501119c3e74cecbf23b1c8 Author: Ryan Chia Date: Tue Nov 12 15:23:44 2024 +0800 asd commit d3eb518711444100d107b53dff555735a18a5cc4 Author: Ryan Chia Date: Tue Nov 12 15:21:42 2024 +0800 asd commit 75559763d8bba422279f725250eab82bcd8e29e0 Author: Ryan Chia Date: Tue Nov 12 15:07:33 2024 +0800 asd commit 3657a9c493956ca91a3a6f40ecb624c0c1e7edf4 Author: Ryan Chia Date: Tue Nov 12 15:05:03 2024 +0800 asd commit 64e2651e87df7f34a684b2fadba6b5f2b8a1a0b0 Author: Ryan Chia Date: Tue Nov 12 15:00:01 2024 +0800 asd commit 4c405f4abeea7037ee8e00793d304fd0cc852b04 Author: Ryan Chia Date: Tue Nov 12 14:57:22 2024 +0800 asd commit c4ccd113e48496d0c397e6dc74b15fc4d004c56d Merge: e400a71 31a6bd1 Author: chiaryan <53717471+chiaryan@users.noreply.github.com> Date: Tue Nov 12 14:54:30 2024 +0800 Merge branch 'staging' into browser-tests commit e400a7176baaa4e272963760be97de84c9bf943a Author: Ryan Chia Date: Tue Nov 12 14:53:23 2024 +0800 asd commit e92e18608afc9a882da7568bfffbe0b96cf01146 Author: Ryan Chia Date: Tue Nov 12 14:47:29 2024 +0800 asd commit 3a975ffd4232f436bc9c817df17cd7312086e66f Author: Ryan Chia Date: Tue Nov 12 14:37:56 2024 +0800 asd commit 96636881de0af527908c2a9b97694940c74ad806 Author: Ryan Chia Date: Tue Nov 12 14:19:17 2024 +0800 asd add browsers commit b0b9fb5e1a4b6440e7e48015daa2cde648fae3c3 Merge: bf9f160 f86888b Author: Ryan Chia Date: Tue Nov 12 14:18:56 2024 +0800 Merge branch 'browser-compatibility-tests' into browser-tests commit 31a6bd1f882c4776b60029b1c1d1852f39201824 Merge: 7d931ee 3fd5752 Author: Benjamin Soh Zikang <97374822+bensohh@users.noreply.github.com> Date: Tue Nov 12 10:20:13 2024 +0800 Merge pull request #71 from CS3219-AY2425S1/titus/fix-local-storage-bug fix(frontend): :bug: mount component before accessing local storage commit 3fd5752dc19a7eca8be962f2dcaa2d13c7c61167 Merge: fdce97a 7d931ee Author: Benjamin Soh Zikang <97374822+bensohh@users.noreply.github.com> Date: Mon Nov 11 12:40:38 2024 +0800 Merge branch 'staging' into titus/fix-local-storage-bug commit 7d931eebf8b778a540b23fb49a524b30b3b8787e Merge: 439b410 d75215c Author: Benjamin Soh Zikang <97374822+bensohh@users.noreply.github.com> Date: Mon Nov 11 12:20:10 2024 +0800 Merge pull request #70 from CS3219-AY2425S1/titus/add-message-queue feat: add message queue commit bf9f160e2b80ac46cb3ac3baf817866f2dd7a6b3 Merge: 862051a 311be82 Author: Ryan Chia Date: Mon Nov 11 04:56:37 2024 +0800 Merge branch 'browser-compatibility-tests' into browser-tests commit 862051a6c53d75de3255c07deacaa6ed41156367 Author: Ryan Chia Date: Sun Nov 10 21:16:04 2024 +0800 asd commit f58f0351a0f83babfcc755ed4b4fc0909ed3cc09 Author: Ryan Chia Date: Sun Nov 10 21:13:59 2024 +0800 asd commit c78449683241496b903e01b143093f07c42c7e4c Author: Ryan Chia Date: Sun Nov 10 21:00:52 2024 +0800 asd commit 2f97a34c78b31c528b9d95cb247281236114f0a5 Author: Ryan Chia Date: Sun Nov 10 20:45:26 2024 +0800 asd commit cccfa548c8833c97d17d63f833bd73a1781825a4 Author: Ryan Chia Date: Sun Nov 10 20:44:24 2024 +0800 install pnpm commit 3570555db6221f063e29670e9110f5b2dda79bb4 Author: Ryan Chia Date: Sun Nov 10 20:32:56 2024 +0800 asd commit 45ebeb433a3ca542a98fd90e1ab31092d5bc49f2 Author: Ryan Chia Date: Sun Nov 10 20:32:04 2024 +0800 asd commit f1e7e40222a3f96cce21e6df3d4596c7f257ee71 Author: Ryan Chia Date: Sun Nov 10 20:08:35 2024 +0800 asd commit f5b521a2f4d26ec5207df63c2e128f4d05551801 Author: Ryan Chia Date: Sun Nov 10 20:08:03 2024 +0800 asd commit cc46721c40d11b60c05287e0facbc9c69a0399a7 Author: Ryan Chia Date: Sun Nov 10 13:47:37 2024 +0800 asd commit 9f1efaffdee71440839ca67e2ed7f39e1c0bec9a Author: Ryan Chia Date: Sun Nov 10 11:55:18 2024 +0800 asd s commit 67960833336c4c9818983f855ad11d72eb03b454 Author: Ryan Chia Date: Sun Nov 10 11:32:00 2024 +0800 asd commit 5b79d8be4f25309d4cfe05a61d5a406ddfccf0c6 Author: Ryan Chia Date: Sun Nov 10 11:28:49 2024 +0800 asd commit 240c839afa0bd5fc4690b9c2e8d0b74f45d69b59 Author: Ryan Chia Date: Sun Nov 10 11:27:52 2024 +0800 asd commit 8958cb6151a2423236ab8c5527ddc464b5185079 Author: Ryan Chia Date: Sun Nov 10 11:23:29 2024 +0800 asd commit ab4cc476f7ba56be6b9e0ef2106133a6b835ac17 Author: Ryan Chia Date: Sun Nov 10 11:22:05 2024 +0800 try selenium test commit 9656decd3259bcc36511e47b5e4800571c3c56bb Merge: 439b410 324463e Author: Ryan Chia Date: Sat Nov 9 16:14:56 2024 +0800 Merge branch 'commit-signalling-.dockerignore' into browser-tests commit fdce97ae834ba27204624fa648695b31175c4645 Author: tituschewxj Date: Fri Nov 8 14:17:53 2024 +0800 fix(videoPanel): :bug: default for undefined partnerId Include a check to validate if partnerID is not undefined commit e5e41ce92afd50a32eef8e3889315ba4f56d4eaa Author: tituschewxj Date: Thu Nov 7 14:07:00 2024 +0800 fix(frontend): :bug: mounts component before accessing local storage Only access localStorage on the client side (in the browser) after the component has mounted. commit d75215c120d6b03c06ac889be0e769fa4dc8122d Author: tituschewxj Date: Thu Nov 7 10:40:15 2024 +0800 style(execution-service): :fire: remove commented code Revmoes the previous commented implementation of sending the submission to history service via REST API call. commit fac44307e888ab2a9c72699fa6a329a847f224a7 Author: tituschewxj Date: Thu Nov 7 01:20:36 2024 +0800 docs: update readme commit 2b2bbd59a6c1be61563db2ee1e0e9ff7fc4b73cb Author: tituschewxj Date: Thu Nov 7 01:12:41 2024 +0800 docs: update readme commit 95a82dc161702934cf68a40368d3a74ab2235fe4 Author: tituschewxj Date: Thu Nov 7 01:10:12 2024 +0800 ci: update docker compose test commit bf0c096955050d55b544b487a70f617eb284def6 Author: tituschewxj Date: Thu Nov 7 01:07:32 2024 +0800 docs: update readme commit b8e3004f8d21268f0f7c42eec4fe3deb83b53203 Author: tituschewxj Date: Thu Nov 7 00:54:53 2024 +0800 docs: update readme commit 8bd3d10c71bf007fb2723d5fcd81ef45e088e36a Author: tituschewxj Date: Thu Nov 7 00:52:29 2024 +0800 feat: update readme commit fbd3a4de76d4f1254c6943c01dc40f14816d7fde Author: tituschewxj Date: Thu Nov 7 00:45:09 2024 +0800 feat: update log msg commit 64a1badcfebdedcef17f31d6539c747b05481588 Author: tituschewxj Date: Thu Nov 7 00:33:50 2024 +0800 fix: update docker-compose commit e48bc7ea91cf62bb9661613fefe0194b71ed3525 Author: tituschewxj Date: Wed Nov 6 23:17:41 2024 +0800 feat: update docker compose commit 8a0e046576e4469d485ca3f11128d3419d330069 Author: tituschewxj Date: Wed Nov 6 23:17:35 2024 +0800 feat: implement rabbitmq msg queue commit 324463e3b1ae0812202668ebeacdd1f13c4b7b64 Author: Ryan Chia Date: Wed Nov 6 01:33:41 2024 +0800 branch name --- .github/workflows/test.yml | 28 ++-- apps/docker-compose.yml | 24 +++- apps/execution-service/.env.example | 2 + apps/execution-service/README.md | 123 +++++++++++------- apps/execution-service/go.mod | 1 + apps/execution-service/go.sum | 2 + apps/execution-service/handlers/submit.go | 33 +---- apps/execution-service/main.go | 18 +-- .../messagequeue/rabbitmq.go | 78 +++++++++++ apps/execution-service/utils/log.go | 9 ++ .../__tests__/browser-tests/browser.test.ts | 42 ++++-- .../src/app/collaboration/[id]/page.tsx | 59 ++++++++- .../CollaborativeEditor.tsx | 47 +++---- .../src/components/VideoPanel/VideoPanel.tsx | 20 ++- apps/history-service/.env.example | 8 +- apps/history-service/README.md | 27 +++- apps/history-service/databases/history.go | 32 +++++ apps/history-service/go.mod | 1 + apps/history-service/go.sum | 2 + apps/history-service/handlers/create.go | 19 +-- apps/history-service/main.go | 16 ++- apps/history-service/messagequeue/rabbitmq.go | 108 +++++++++++++++ apps/history-service/utils/log.go | 9 ++ 23 files changed, 543 insertions(+), 165 deletions(-) create mode 100644 apps/execution-service/messagequeue/rabbitmq.go create mode 100644 apps/execution-service/utils/log.go create mode 100644 apps/history-service/databases/history.go create mode 100644 apps/history-service/messagequeue/rabbitmq.go create mode 100644 apps/history-service/utils/log.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8d18e13b1c..fe4ee21edc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 - + - name: Set up .env env: QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} @@ -30,7 +30,7 @@ jobs: echo "FIREBASE_CREDENTIAL_PATH=$QUESTION_FIREBASE_CREDENTIAL_PATH" >> .env echo "JWT_SECRET=$JWT_SECRET" >> .env echo "EXECUTION_SERVICE_URL=$EXECUTION_SERVICE_URL" >> .env - + - name: Set up credentials env: QUESTION_FIREBASE_JSON: ${{ secrets.QUESTION_SERVICE_FIREBASE_CREDENTIAL }} @@ -41,8 +41,8 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 - with: - go-version: '1.23.x' + with: + go-version: "1.23.x" - name: Install Go dependencies run: | @@ -51,7 +51,7 @@ jobs: - name: Install firebase tools run: curl -sL firebase.tools | bash - + - name: Run Go tests with Firebase emulator run: firebase emulators:exec --only firestore 'cd ./apps/question-service; go test -v ./tests' @@ -66,11 +66,11 @@ jobs: run: | cd ./apps/frontend cp .env.example .env - + - name: Set up Node.js uses: actions/setup-node@v2 with: - node-version: '22' + node-version: "22" - name: Install pnpm run: npm i -g pnpm @@ -227,17 +227,25 @@ jobs: uses: pnpm/action-setup@v4 with: version: 9.1.4 - + - name: Install dependencies run: | cd ./apps/frontend pnpm i - + - name: Install Chrome WebDriver uses: nanasess/setup-chromedriver@v2 with: chromedriver-version: '130.0.6723.116' - + + - name: Install Edge + uses: browser-actions/setup-edge@v1 + with: + edge-version: stable + + - name: Install Geckodriver + uses: browser-actions/setup-geckodriver@latest + - name: Run Browser Test run: | cd ./apps/frontend diff --git a/apps/docker-compose.yml b/apps/docker-compose.yml index a0565fe1dd..12d02b5661 100644 --- a/apps/docker-compose.yml +++ b/apps/docker-compose.yml @@ -68,7 +68,9 @@ services: - apps_network volumes: - ./history-service:/history-service - + depends_on: + - rabbitmq + signalling-service: build: context: ./signalling-service @@ -95,6 +97,8 @@ services: volumes: - ./execution-service:/execution-service - /var/run/docker.sock:/var/run/docker.sock + depends_on: + - rabbitmq redis: image: redis:latest @@ -104,6 +108,19 @@ services: - 6379:6379 container_name: redis-container + rabbitmq: + image: rabbitmq:3-management + networks: + - apps_network + ports: + - 5672:5672 # Port for RabbitMQ message broker + - 15672:15672 # Port for RabbitMQ Management UI + environment: + RABBITMQ_DEFAULT_USER: guest + RABBITMQ_DEFAULT_PASS: guest + volumes: + - rabbitmq_data:/var/lib/rabbitmq + python-sandbox: build: context: ./execution-service/execution/python @@ -114,3 +131,8 @@ services: networks: apps_network: + +volumes: + # Mounts a volume for RabbitMQ data persistence. + # This ensures that data is not lost when the container is restarted or removed. + rabbitmq_data: diff --git a/apps/execution-service/.env.example b/apps/execution-service/.env.example index 6a1fb0bd86..4122078fbd 100644 --- a/apps/execution-service/.env.example +++ b/apps/execution-service/.env.example @@ -3,6 +3,8 @@ PORT=8083 # If you are NOT USING docker, use the below variables # HISTORY_SERVICE_URL=http://localhost:8082/ +# RABBITMQ_URL=amqp://guest:guest@localhost:5672/ # If you are USING docker, use the below variables HISTORY_SERVICE_URL=http://history-service:8082/ +RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672/ diff --git a/apps/execution-service/README.md b/apps/execution-service/README.md index 2961ed152e..c53dc3ab9f 100644 --- a/apps/execution-service/README.md +++ b/apps/execution-service/README.md @@ -20,7 +20,32 @@ go run main.go The server will be available at http://localhost:8083. -## Running the Application via Docker +### Setting up message queue with RabbitMQ + +A message queue is used to pass submission results asynchronously from the execution-service to the history-service. + +1. In order to do so, we can run the following command to set up a docker container for RabbitMQ: + +```bash +docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management +``` + +2. Then we can run the execution-service: + +```bash +go run main.go +``` + +3. We can run the history-service by changing our directory and running the same command: + +```bash +cd ../history-service +go run main.go +``` + +To view more details on the RabbitMQ queue, we can go to `localhost:15672`, and login using `guest` as the username and password. + +### Running the Application via Docker To run the application via Docker, run the following command: @@ -74,10 +99,10 @@ The following json format will be returned: ```json [ - { - "input":"hello", - "expected":"olleh" - } + { + "input": "hello", + "expected": "olleh" + } ] ``` @@ -98,16 +123,16 @@ The following json format will be returned: ```json { - "visibleTestResults":[ + "visibleTestResults": [ { - "input":"hello", - "expected":"olleh", - "actual":"olleh", - "passed":true, - "error":"" + "input": "hello", + "expected": "olleh", + "actual": "olleh", + "passed": true, + "error": "" } ], - "customTestResults":null + "customTestResults": null } ``` @@ -127,29 +152,29 @@ The following json format will be returned: ```json { - "visibleTestResults":[ + "visibleTestResults": [ { - "input":"hello", - "expected":"olleh", - "actual":"olleh", - "passed":true, - "error":"" + "input": "hello", + "expected": "olleh", + "actual": "olleh", + "passed": true, + "error": "" } ], - "customTestResults":[ + "customTestResults": [ { - "input":"Hannah", - "expected":"hannaH", - "actual":"hannaH", - "passed":true, - "error":"" + "input": "Hannah", + "expected": "hannaH", + "actual": "hannaH", + "passed": true, + "error": "" }, { - "input":"abcdefg", - "expected":"gfedcba", - "actual":"gfedcba", - "passed":true, - "error":"" + "input": "abcdefg", + "expected": "gfedcba", + "actual": "gfedcba", + "passed": true, + "error": "" } ] } @@ -178,20 +203,20 @@ The following json format will be returned: ```json { - "visibleTestResults":[ + "visibleTestResults": [ { - "input":"hello", - "expected":"olleh", - "actual":"olleh", - "passed":true, - "error":"" + "input": "hello", + "expected": "olleh", + "actual": "olleh", + "passed": true, + "error": "" } ], - "hiddenTestResults":{ - "passed":2, - "total":2 + "hiddenTestResults": { + "passed": 2, + "total": 2 }, - "status":"Accepted" + "status": "Accepted" } ``` @@ -199,19 +224,19 @@ If compilation error exists or any of the tests (visible and hidden) fails, stat ```json { - "visibleTestResults":[ + "visibleTestResults": [ { - "input":"hello", - "expected":"olleh", - "actual":"", - "passed":false, - "error":"Command execution failed: Traceback (most recent call last):\n File \"/tmp/4149249165.py\", line 2, in \u003cmodule\u003e\n prit(name[::-1])\n ^^^^\nNameError: name 'prit' is not defined. Did you mean: 'print'?\n: %!w(*exec.ExitError=\u0026{0x4000364678 []})" + "input": "hello", + "expected": "olleh", + "actual": "", + "passed": false, + "error": "Command execution failed: Traceback (most recent call last):\n File \"/tmp/4149249165.py\", line 2, in \u003cmodule\u003e\n prit(name[::-1])\n ^^^^\nNameError: name 'prit' is not defined. Did you mean: 'print'?\n: %!w(*exec.ExitError=\u0026{0x4000364678 []})" } ], - "hiddenTestResults":{ - "passed":0, - "total":2 + "hiddenTestResults": { + "passed": 0, + "total": 2 }, - "status":"Attempted" + "status": "Attempted" } ``` diff --git a/apps/execution-service/go.mod b/apps/execution-service/go.mod index 32a516cf23..aff484d2a7 100644 --- a/apps/execution-service/go.mod +++ b/apps/execution-service/go.mod @@ -31,6 +31,7 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.13.0 // indirect + github.com/rabbitmq/amqp091-go v1.10.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect diff --git a/apps/execution-service/go.sum b/apps/execution-service/go.sum index 7d3c75e147..8a595690fa 100644 --- a/apps/execution-service/go.sum +++ b/apps/execution-service/go.sum @@ -85,6 +85,8 @@ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= +github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= diff --git a/apps/execution-service/handlers/submit.go b/apps/execution-service/handlers/submit.go index 0bd06656a3..1411ffcea7 100644 --- a/apps/execution-service/handlers/submit.go +++ b/apps/execution-service/handlers/submit.go @@ -1,16 +1,16 @@ package handlers import ( - "bytes" "encoding/json" "execution-service/constants" + "execution-service/messagequeue" "execution-service/models" "execution-service/utils" "fmt" + "net/http" + "github.com/go-chi/chi/v5" "google.golang.org/api/iterator" - "net/http" - "os" ) func (s *Service) ExecuteVisibleAndHiddenTestsAndSubmit(w http.ResponseWriter, r *http.Request) { @@ -61,7 +61,6 @@ func (s *Service) ExecuteVisibleAndHiddenTestsAndSubmit(w http.ResponseWriter, r } // Save the collaboration history via the history-service - // TODO: convert to message queue submissionReq := models.Submission{ Code: submission.Code, Language: submission.Language, @@ -84,34 +83,12 @@ func (s *Service) ExecuteVisibleAndHiddenTestsAndSubmit(w http.ResponseWriter, r return } - // get history-service url from os env - historyServiceUrl := os.Getenv("HISTORY_SERVICE_URL") - if historyServiceUrl == "" { - http.Error(w, "HISTORY_SERVICE_URL is not set", http.StatusInternalServerError) - return - } - - req, err := http.NewRequest(http.MethodPost, historyServiceUrl+"histories", - bytes.NewBuffer(jsonData)) + err = messagequeue.PublishSubmissionMessage(jsonData) if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("Failed to save submission history: %v", err), http.StatusInternalServerError) return } - req.Header.Set("Content-Type", "application/json") - - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - http.Error(w, "Failed to save submission history", http.StatusInternalServerError) - } - w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(testResults) diff --git a/apps/execution-service/main.go b/apps/execution-service/main.go index 706d0afcd6..e2da2948be 100644 --- a/apps/execution-service/main.go +++ b/apps/execution-service/main.go @@ -3,6 +3,8 @@ package main import ( "context" "execution-service/handlers" + "execution-service/messagequeue" + "execution-service/utils" "fmt" "log" "net/http" @@ -21,20 +23,20 @@ import ( func main() { // Load .env file err := godotenv.Load() - if err != nil { - log.Fatal("Error loading .env file") - } + utils.FailOnError(err, "Error loading .env file") // Initialize Firestore client ctx := context.Background() client, err := initFirestore(ctx) - if err != nil { - log.Fatalf("Failed to initialize Firestore client: %v", err) - } + utils.FailOnError(err, "Failed to initialize Firestore client") defer client.Close() service := &handlers.Service{Client: client} + amqpConnection, amqpChannel := messagequeue.InitRabbitMQServer() + defer amqpConnection.Close() + defer amqpChannel.Close() + r := initChiRouter(service) initRestServer(r) } @@ -107,7 +109,5 @@ func initRestServer(r *chi.Mux) { // Start the server log.Printf("Starting REST server on http://localhost:%s", port) err := http.ListenAndServe(fmt.Sprintf(":%s", port), r) - if err != nil { - log.Fatalf("Failed to start server: %v", err) - } + utils.FailOnError(err, "Failed to start REST server") } diff --git a/apps/execution-service/messagequeue/rabbitmq.go b/apps/execution-service/messagequeue/rabbitmq.go new file mode 100644 index 0000000000..1a6aafcde7 --- /dev/null +++ b/apps/execution-service/messagequeue/rabbitmq.go @@ -0,0 +1,78 @@ +package messagequeue + +import ( + "execution-service/utils" + "fmt" + "log" + "os" + "time" + + amqp "github.com/rabbitmq/amqp091-go" +) + +const ( + CODE_SUBMISSION_QUEUE_KEY = "code-submission" + NUM_RETRIES = 10 +) + +var ( + codeSubmissionQueue amqp.Queue + rabbitMQChannel *amqp.Channel +) + +func InitRabbitMQServer() (*amqp.Connection, *amqp.Channel) { + conn := connectToRabbitMQ() + + // Create a channel + ch, err := conn.Channel() + utils.FailOnError(err, "Failed to open a channel") + rabbitMQChannel = ch + + // Declare a queue + q, err := ch.QueueDeclare( + CODE_SUBMISSION_QUEUE_KEY, // name + false, // durable + false, // delete when unused + false, // exclusive + false, // no-wait + nil, // arguments + ) + utils.FailOnError(err, "Failed to declare a queue") + codeSubmissionQueue = q + + return conn, ch +} + +func connectToRabbitMQ() *amqp.Connection { + var conn *amqp.Connection + var err error + rabbitMQURL := os.Getenv("RABBITMQ_URL") + for i := 0; i < NUM_RETRIES; i++ { // Retry up to 10 times + conn, err = amqp.Dial(rabbitMQURL) + if err == nil { + log.Println("Connected to RabbitMQ") + return conn + } + log.Printf("Failed to connect to RabbitMQ, retrying in 5 seconds... (Attempt %d/%d)", i+1, NUM_RETRIES) + time.Sleep(5 * time.Second) + } + utils.FailOnError(err, fmt.Sprintf("Failed to connect to RabbitMQ after %d attempts", NUM_RETRIES)) + return nil +} + +func PublishSubmissionMessage(submission []byte) error { + err := rabbitMQChannel.Publish( + "", // exchange + codeSubmissionQueue.Name, // routing key + false, // mandatory + false, // immediate + amqp.Publishing{ + ContentType: "application/json", + Body: submission, + }) + if err != nil { + return fmt.Errorf("Failed to publish a message: %v", err) + } + log.Printf("RabbitMQ: [x] Sent %s", submission) + return nil +} diff --git a/apps/execution-service/utils/log.go b/apps/execution-service/utils/log.go new file mode 100644 index 0000000000..a77b2c29ca --- /dev/null +++ b/apps/execution-service/utils/log.go @@ -0,0 +1,9 @@ +package utils + +import "log" + +func FailOnError(err error, msg string) { + if err != nil { + log.Fatalf("%s: %s", msg, err) + } +} diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 22257250c3..20b49ba1bd 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -1,37 +1,61 @@ -import { Actions, Browser, Builder, By, Key, until, WebDriver } from "selenium-webdriver" +import { Actions, Browser, Builder, By, Capabilities, Key, until, WebDriver } from "selenium-webdriver" + +import {Options as ChromeOptions} from "selenium-webdriver/chrome" +import {Options as EdgeOptions} from "selenium-webdriver/edge" +import {Options as FirefoxOptions} from "selenium-webdriver/firefox" -import Chrome from "selenium-webdriver/chrome" const URL = 'http://localhost:3000/'; const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjk5OTk5OTk5OTk5fQ.Z4_FVGQ5lIcouP3m4YLMr6pGMF17IJFfo2yOTiN58DY" -describe("chrome browser", () => { - const options = new Chrome.Options() - .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action - const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); +const CHROME_OPTIONS = new ChromeOptions() + .addArguments("--headless=new") as ChromeOptions; // uncomment locally to see the steps in action +const EDGE_OPTIONS = new EdgeOptions() + .setBinaryPath("/opt/hostedtoolcache/msedge/stable/x64/msedge") // need to point to the correct path + .addArguments("--headless=new") as EdgeOptions; + +const FIREFOX_OPTIONS = new FirefoxOptions() + .addArguments("--headless") as FirefoxOptions; + +const builder = new Builder() + .setChromeOptions(CHROME_OPTIONS) + .setEdgeOptions(EDGE_OPTIONS) + .setFirefoxOptions(FIREFOX_OPTIONS) + +describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", (browser) => { let driver: WebDriver; + beforeAll(() => { + const cap = new Capabilities().setBrowserName(browser) + builder.withCapabilities(cap); + }) beforeEach(async () => { + console.log(browser + ": building..."); driver = await builder.build(); + console.log(browser + ": built"); }) afterEach(async () => { await driver.quit(); }) - describe("chrome webdriver installed correctly", () => { + describe("webdriver installed correctly", () => { it("does google search", async () => { + console.log("getting url"); await driver.get('http://www.google.com'); + console.log("got url"); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); + console.log("did search"); }, 10000); - it("does another google search", async () => { + + it.skip("does another google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); }, 10000); }); - describe("browser-test", () => { + describe.skip("browser-test", () => { it("accesses and login to peerprep", async () => { await driver.get(URL); await driver.wait(until.urlIs(`${URL}login`)); diff --git a/apps/frontend/src/app/collaboration/[id]/page.tsx b/apps/frontend/src/app/collaboration/[id]/page.tsx index 6ae67427ef..739eac08a6 100644 --- a/apps/frontend/src/app/collaboration/[id]/page.tsx +++ b/apps/frontend/src/app/collaboration/[id]/page.tsx @@ -34,9 +34,12 @@ import { ExecuteVisibleAndHiddenTestsAndSubmit, ExecutionResults, GetVisibleTests, + isTestResult, SubmissionHiddenTestResultsAndStatus, SubmissionResults, Test, + TestData, + TestResult, } from "@/app/services/execute"; import { QuestionDetailFull } from "@/components/question/QuestionDetailFull/QuestionDetailFull"; import VideoPanel from "@/components/VideoPanel/VideoPanel"; @@ -75,15 +78,17 @@ export default function CollaborationPage(props: CollaborationProps) { ); const [currentUser, setCurrentUser] = useState(undefined); const [matchedUser, setMatchedUser] = useState("Loading..."); - const [sessionDuration, setSessionDuration] = useState(() => { - const storedTime = localStorage.getItem("session-duration"); - return storedTime ? parseInt(storedTime) : 0; - }); // State for count-up timer (TODO: currently using localstorage to store time, change to db stored time in the future) + const [sessionDuration, setSessionDuration] = useState(0); // State for count-up timer (TODO: currently using localstorage to store time, change to db stored time in the future) const stopwatchRef = useRef(null); const [matchedTopics, setMatchedTopics] = useState( undefined ); + useEffect(() => { + const storedTime = localStorage.getItem("session-duration"); + setSessionDuration(storedTime ? parseInt(storedTime) : 0); + }, []); + // Chat states const [messageToSend, setMessageToSend] = useState( undefined @@ -314,6 +319,52 @@ export default function CollaborationPage(props: CollaborationProps) { } }, [isSessionEndModalOpen, countDown]); + // Tabs component items for visibleTestCases + var items: TabsProps["items"] = visibleTestCases.map((item, index) => { + return { + key: index.toString(), + label: ( + + Case {index + 1} + + ), + children: ( +
+ + {isTestResult(item) && ( +
+ + + {item.passed ? "Passed" : "Failed"} + +
+ Actual Output:{" "} + {item.actual} +
+ {item.error && ( + <> + Error: +
{item.error}
+ + )} +
+ )} +
+ ), + }; + }); + // Handles the cleaning of localstorage variables, stopping the timer & signalling collab user on webrtc // type: "initiator" | "peer" const handleCloseCollaboration = (type: string) => { diff --git a/apps/frontend/src/components/CollaborativeEditor/CollaborativeEditor.tsx b/apps/frontend/src/components/CollaborativeEditor/CollaborativeEditor.tsx index a7c8051bcf..d32f67612d 100644 --- a/apps/frontend/src/components/CollaborativeEditor/CollaborativeEditor.tsx +++ b/apps/frontend/src/components/CollaborativeEditor/CollaborativeEditor.tsx @@ -15,8 +15,8 @@ import * as Y from "yjs"; import { yCollab } from "y-codemirror.next"; import { WebrtcProvider } from "y-webrtc"; import { EditorView, basicSetup } from "codemirror"; -import { keymap } from "@codemirror/view" -import { indentWithTab } from "@codemirror/commands" +import { keymap } from "@codemirror/view"; +import { indentWithTab } from "@codemirror/commands"; import { EditorState, Compartment } from "@codemirror/state"; import { javascript, javascriptLanguage } from "@codemirror/lang-javascript"; import { python, pythonLanguage } from "@codemirror/lang-python"; @@ -68,15 +68,15 @@ interface Awareness { executionResultsState: { executionResults: ExecutionResults; id: number; - } + }; executingState: { executing: boolean; id: number; - } + }; submittingState: { submitting: boolean; id: number; - } + }; } export const usercolors = [ @@ -111,8 +111,7 @@ const CollaborativeEditor = forwardRef( props.onCodeChange(update.state.doc.toString()); } }); - - + // Referenced: https://codemirror.net/examples/config/#dynamic-configuration // const autoLanguage = EditorState.transactionExtender.of((tr) => { // if (!tr.docChanged) return null; @@ -196,10 +195,10 @@ const CollaborativeEditor = forwardRef( }); }; - let latestExecutionId: number = (new Date(0)).getTime(); - let latestSubmissionId: number = (new Date(0)).getTime(); - let latestExecutingId: number = (new Date(0)).getTime(); - let latestSubmittingId: number = (new Date(0)).getTime(); + let latestExecutionId: number = new Date(0).getTime(); + let latestSubmissionId: number = new Date(0).getTime(); + let latestExecutingId: number = new Date(0).getTime(); + let latestSubmittingId: number = new Date(0).getTime(); useImperativeHandle(ref, () => ({ endSession: () => { @@ -311,12 +310,14 @@ const CollaborativeEditor = forwardRef( .get(clientID) as Awareness; if ( - state && + state && state.submissionResultsState && state.submissionResultsState.id !== latestSubmissionId ) { latestSubmissionId = state.submissionResultsState.id; - props.updateSubmissionResults(state.submissionResultsState.submissionResults); + props.updateSubmissionResults( + state.submissionResultsState.submissionResults + ); messageApi.open({ type: "success", content: `${ @@ -326,12 +327,14 @@ const CollaborativeEditor = forwardRef( } if ( - state && - state.executionResultsState && + state && + state.executionResultsState && state.executionResultsState.id !== latestExecutionId ) { latestExecutionId = state.executionResultsState.id; - props.updateExecutionResults(state.executionResultsState.executionResults); + props.updateExecutionResults( + state.executionResultsState.executionResults + ); messageApi.open({ type: "success", content: `${ @@ -341,8 +344,8 @@ const CollaborativeEditor = forwardRef( } if ( - state && - state.executingState && + state && + state.executingState && state.executingState.id !== latestExecutingId ) { latestExecutingId = state.executingState.id; @@ -358,8 +361,8 @@ const CollaborativeEditor = forwardRef( } if ( - state && - state.submittingState && + state && + state.submittingState && state.submittingState.id !== latestSubmittingId ) { latestSubmittingId = state.submittingState.id; @@ -367,9 +370,7 @@ const CollaborativeEditor = forwardRef( if (state.submittingState.submitting) { messageApi.open({ type: "info", - content: `${ - props.matchedUser ?? "Peer" - } is saving code...`, + content: `${props.matchedUser ?? "Peer"} is saving code...`, }); } } diff --git a/apps/frontend/src/components/VideoPanel/VideoPanel.tsx b/apps/frontend/src/components/VideoPanel/VideoPanel.tsx index 36fdd948e2..2db62642e0 100644 --- a/apps/frontend/src/components/VideoPanel/VideoPanel.tsx +++ b/apps/frontend/src/components/VideoPanel/VideoPanel.tsx @@ -11,11 +11,8 @@ import { } from "@ant-design/icons"; const VideoPanel = () => { - const matchId = localStorage.getItem("collabId")?.toString() ?? ""; - const currentUsername = localStorage.getItem("user")?.toString(); - const matchedUsername = localStorage.getItem("matchedUser")?.toString(); - const currentId = currentUsername + "-" + matchId ?? ""; - const partnerId = matchedUsername + "-" + matchId ?? ""; + const [currentId, setCurrentId] = useState(); + const [partnerId, setPartnerId] = useState(); const remoteVideoRef = useRef(null); const currentUserVideoRef = useRef(null); @@ -30,6 +27,15 @@ const VideoPanel = () => { const [muteOn, setMuteOn] = useState(false); const [isCalling, setIsCalling] = useState(false); + useEffect(() => { + const matchId = localStorage.getItem("collabId")?.toString() ?? ""; + const currentUsername = localStorage.getItem("user")?.toString(); + const matchedUsername = localStorage.getItem("matchedUser")?.toString(); + + setCurrentId(currentUsername + "-" + (matchId ?? "")); + setPartnerId(matchedUsername + "-" + (matchId ?? "")); + }, []); + const handleCall = () => { navigator.mediaDevices .getUserMedia({ @@ -37,7 +43,7 @@ const VideoPanel = () => { audio: true, }) .then((stream) => { - if (peerInstance) { + if (peerInstance && partnerId) { const call = peerInstance?.call(partnerId, stream); setCallInstance(call); setIsCalling(true); // Set isCalling as true since it is the initiator @@ -120,7 +126,7 @@ const VideoPanel = () => { } }; } - }, []); + }, [currentId]); // When remote peer initiates end call, we set isCalling to false useEffect(() => { diff --git a/apps/history-service/.env.example b/apps/history-service/.env.example index b3bd4db2b4..0f3f18c101 100644 --- a/apps/history-service/.env.example +++ b/apps/history-service/.env.example @@ -1,2 +1,8 @@ FIREBASE_CREDENTIAL_PATH=cs3219-staging-codehisto-bb61c-firebase-adminsdk-egopb-95cfaf9b87.json -PORT=8082 \ No newline at end of file +PORT=8082 + +# If you are NOT USING docker, use the below variables +# RABBITMQ_URL=amqp://guest:guest@localhost:5672/ + +# If you are USING docker, use the below variables +RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672/ \ No newline at end of file diff --git a/apps/history-service/README.md b/apps/history-service/README.md index 681c629bcd..6fec9e5bbd 100644 --- a/apps/history-service/README.md +++ b/apps/history-service/README.md @@ -47,9 +47,34 @@ To start the server, run the following command: go run main.go ``` +### Setting up message queue with RabbitMQ + +A message queue is used to pass submission results asynchronously from the execution-service to the history-service. + +1. In order to do so, we can run the following command to set up a docker container for RabbitMQ: + +```bash +docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management +``` + +2. Then we can run the history-service: + +```bash +go run main.go +``` + +3. We can run the execution-service by changing our directory and running the same command: + +```bash +cd ../execution-service +go run main.go +``` + +To view more details on the RabbitMQ queue, we can go to `localhost:15672`, and login using `guest` as the username and password. + The server will be available at http://localhost:8082. -## Running the Application via Docker +### Running the Application via Docker To run the application via Docker, run the following command: diff --git a/apps/history-service/databases/history.go b/apps/history-service/databases/history.go new file mode 100644 index 0000000000..e9b41e4b14 --- /dev/null +++ b/apps/history-service/databases/history.go @@ -0,0 +1,32 @@ +package databases + +import ( + "context" + "history-service/models" + + "cloud.google.com/go/firestore" +) + +func CreateHistory(client *firestore.Client, ctx context.Context, submissionHistory models.SubmissionHistory) (*firestore.DocumentRef, error) { + // Document reference ID in firestore mapped to the match ID in model + collection := client.Collection("collaboration-history") + + docRef, _, err := collection.Add(ctx, map[string]interface{}{ + "title": submissionHistory.Title, + "code": submissionHistory.Code, + "language": submissionHistory.Language, + "user": submissionHistory.User, + "matchedUser": submissionHistory.MatchedUser, + "matchedTopics": submissionHistory.MatchedTopics, + "questionDocRefId": submissionHistory.QuestionDocRefID, + "questionDifficulty": submissionHistory.QuestionDifficulty, + "questionTopics": submissionHistory.QuestionTopics, + "status": submissionHistory.Status, + "createdAt": firestore.ServerTimestamp, + "updatedAt": firestore.ServerTimestamp, + }) + if err != nil { + return nil, err + } + return docRef, nil +} diff --git a/apps/history-service/go.mod b/apps/history-service/go.mod index 37d6005bf1..2bdb4f0c8a 100644 --- a/apps/history-service/go.mod +++ b/apps/history-service/go.mod @@ -31,6 +31,7 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.13.0 // indirect + github.com/rabbitmq/amqp091-go v1.10.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect diff --git a/apps/history-service/go.sum b/apps/history-service/go.sum index ce7234e8f6..fbc00bcfaa 100644 --- a/apps/history-service/go.sum +++ b/apps/history-service/go.sum @@ -85,6 +85,8 @@ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= +github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= diff --git a/apps/history-service/handlers/create.go b/apps/history-service/handlers/create.go index 3dc635d0dd..e4868730b7 100644 --- a/apps/history-service/handlers/create.go +++ b/apps/history-service/handlers/create.go @@ -2,11 +2,11 @@ package handlers import ( "encoding/json" + "history-service/databases" "history-service/models" "history-service/utils" "net/http" - "cloud.google.com/go/firestore" "google.golang.org/api/iterator" ) @@ -22,22 +22,7 @@ func (s *Service) CreateHistory(w http.ResponseWriter, r *http.Request) { } // Document reference ID in firestore mapped to the match ID in model - collection := s.Client.Collection("collaboration-history") - - docRef, _, err := collection.Add(ctx, map[string]interface{}{ - "title": submissionHistory.Title, - "code": submissionHistory.Code, - "language": submissionHistory.Language, - "user": submissionHistory.User, - "matchedUser": submissionHistory.MatchedUser, - "matchedTopics": submissionHistory.MatchedTopics, - "questionDocRefId": submissionHistory.QuestionDocRefID, - "questionDifficulty": submissionHistory.QuestionDifficulty, - "questionTopics": submissionHistory.QuestionTopics, - "status": submissionHistory.Status, - "createdAt": firestore.ServerTimestamp, - "updatedAt": firestore.ServerTimestamp, - }) + docRef, err := databases.CreateHistory(s.Client, ctx, submissionHistory) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/apps/history-service/main.go b/apps/history-service/main.go index 751f2ed525..1b79073caf 100644 --- a/apps/history-service/main.go +++ b/apps/history-service/main.go @@ -3,7 +3,10 @@ package main import ( "context" "fmt" + "history-service/databases" "history-service/handlers" + "history-service/messagequeue" + "history-service/utils" "log" "net/http" "os" @@ -20,20 +23,21 @@ import ( func main() { err := godotenv.Load() - if err != nil { - log.Fatal("Error loading .env file") - } + utils.FailOnError(err, "Error loading .env file") // Initialize Firestore client ctx := context.Background() client, err := initFirestore(ctx) - if err != nil { - log.Fatalf("Failed to initialize Firestore client: %v", err) - } + utils.FailOnError(err, "Failed to initialize Firestore client") defer client.Close() service := &handlers.Service{Client: client} + amqpConnection, amqpChannel := messagequeue.InitRabbitMQServer() + defer amqpConnection.Close() + defer amqpChannel.Close() + go messagequeue.ConsumeSubmissionMessages(client, databases.CreateHistory) + r := initChiRouter(service) initRestServer(r) } diff --git a/apps/history-service/messagequeue/rabbitmq.go b/apps/history-service/messagequeue/rabbitmq.go new file mode 100644 index 0000000000..f945a866d0 --- /dev/null +++ b/apps/history-service/messagequeue/rabbitmq.go @@ -0,0 +1,108 @@ +package messagequeue + +import ( + "context" + "encoding/json" + "fmt" + "history-service/models" + "history-service/utils" + "log" + "os" + "time" + + "cloud.google.com/go/firestore" + amqp "github.com/rabbitmq/amqp091-go" +) + +const ( + CODE_SUBMISSION_QUEUE_KEY = "code-submission" + NUM_RETRIES = 10 +) + +var ( + codeSubmissionQueue amqp.Queue + rabbitMQChannel *amqp.Channel +) + +func InitRabbitMQServer() (*amqp.Connection, *amqp.Channel) { + conn := connectToRabbitMQ() + + // Create a channel + ch, err := conn.Channel() + utils.FailOnError(err, "Failed to open a channel") + rabbitMQChannel = ch + + // Declare a queue + q, err := ch.QueueDeclare( + "code-submission", // name + false, // durable + false, // delete when unused + false, // exclusive + false, // no-wait + nil, // arguments + ) + utils.FailOnError(err, "Failed to declare a queue") + codeSubmissionQueue = q + + return conn, ch +} + +func connectToRabbitMQ() *amqp.Connection { + var conn *amqp.Connection + var err error + rabbitMQURL := os.Getenv("RABBITMQ_URL") + for i := 0; i < NUM_RETRIES; i++ { // Retry up to 10 times + conn, err = amqp.Dial(rabbitMQURL) + if err == nil { + log.Println("Connected to RabbitMQ") + return conn + } + log.Printf("Failed to connect to RabbitMQ, retrying in 5 seconds... (Attempt %d/%d)", i+1, NUM_RETRIES) + time.Sleep(5 * time.Second) + } + utils.FailOnError(err, fmt.Sprintf("Failed to connect to RabbitMQ after %d attempts", NUM_RETRIES)) + return nil +} + +func ConsumeSubmissionMessages(client *firestore.Client, createSubmission func( + *firestore.Client, context.Context, models.SubmissionHistory) ( + *firestore.DocumentRef, error)) { + ctx := context.Background() + + // Consume messages from the queue + msgs, err := rabbitMQChannel.Consume( + codeSubmissionQueue.Name, // queue + "", // consumer + true, // auto-ack + false, // exclusive + false, // no-local + false, // no-wait + nil, // args + ) + utils.FailOnError(err, "RabbitMQ: Failed to register a consumer") + + // Create a channel to block indefinitely + forever := make(chan bool) + + // Start a goroutine to handle incoming messages + go func() { + for d := range msgs { + log.Printf("RabbitMQ: Received a message") + + // Parse request + var submissionHistory models.SubmissionHistory + if err := json.Unmarshal(d.Body, &submissionHistory); err != nil { + log.Printf("RabbitMQ: Error decoding JSON: %v", err) + continue + } + + _, err := createSubmission(client, ctx, submissionHistory) + if err != nil { + log.Printf("RabbitMQ: %v", err) + } + } + }() + + log.Printf("RabbitMQ: [*] Waiting for messages.") + <-forever +} diff --git a/apps/history-service/utils/log.go b/apps/history-service/utils/log.go new file mode 100644 index 0000000000..a77b2c29ca --- /dev/null +++ b/apps/history-service/utils/log.go @@ -0,0 +1,9 @@ +package utils + +import "log" + +func FailOnError(err error, msg string) { + if err != nil { + log.Fatalf("%s: %s", msg, err) + } +} From d3ad549122eeecef76c0ccb5d907df6e94636075 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 15:37:43 +0800 Subject: [PATCH 31/35] quit driver only if present --- apps/frontend/__tests__/browser-tests/browser.test.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 20b49ba1bd..2225308278 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -29,23 +29,20 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", }) beforeEach(async () => { - console.log(browser + ": building..."); driver = await builder.build(); - console.log(browser + ": built"); }) afterEach(async () => { - await driver.quit(); + if (driver) { + await driver.quit(); + } }) describe("webdriver installed correctly", () => { it("does google search", async () => { - console.log("getting url"); await driver.get('http://www.google.com'); - console.log("got url"); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); - console.log("did search"); }, 10000); it.skip("does another google search", async () => { @@ -55,7 +52,7 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", }, 10000); }); - describe.skip("browser-test", () => { + describe("browser-test", () => { it("accesses and login to peerprep", async () => { await driver.get(URL); await driver.wait(until.urlIs(`${URL}login`)); From e3a384ea66346a330f73206b7378f25a608da6bf Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 15:48:19 +0800 Subject: [PATCH 32/35] asd --- apps/frontend/__tests__/browser-tests/browser.test.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 0c6c03c187..6d55979cb4 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -42,12 +42,9 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", describe("webdriver installed correctly", () => { it("does google search", async () => { - console.log("getting url"); await driver.get('http://www.google.com'); - console.log("got url"); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); - console.log("did search"); }, 10000); it.skip("does another google search", async () => { @@ -78,7 +75,7 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", expect(slogan2).toBe("peers"); }, 10000); }) -}) +}, 20000) From 77f62dbeabb27686232fe543c18b0eb4ca157b2d Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 15:54:07 +0800 Subject: [PATCH 33/35] Squashed commit of the following: commit 5dbc8a083ddd10f7ba2065843e88feea63df9e6e Author: Ryan Chia Date: Tue Nov 12 15:50:20 2024 +0800 --- apps/frontend/__tests__/browser-tests/browser.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 6d55979cb4..46fa946f63 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -32,7 +32,7 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", console.log(browser + ": building..."); driver = await builder.build(); console.log(browser + ": built"); - }) + }, 10000) afterEach(async () => { if (driver) { From 1be60da0858de200ad1e6fa0817a45e29f2e0ed1 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 16:06:25 +0800 Subject: [PATCH 34/35] revert to chrome whoops --- .github/workflows/test.yml | 164 +++++++++++++++--- .../__tests__/browser-tests/browser.test.ts | 48 ++--- 2 files changed, 155 insertions(+), 57 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 45d5fcf341..13bcff8e10 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 - + - name: Set up .env env: QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} @@ -30,7 +30,7 @@ jobs: echo "FIREBASE_CREDENTIAL_PATH=$QUESTION_FIREBASE_CREDENTIAL_PATH" >> .env echo "JWT_SECRET=$JWT_SECRET" >> .env echo "EXECUTION_SERVICE_URL=$EXECUTION_SERVICE_URL" >> .env - + - name: Set up credentials env: QUESTION_FIREBASE_JSON: ${{ secrets.QUESTION_SERVICE_FIREBASE_CREDENTIAL }} @@ -41,8 +41,8 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 - with: - go-version: "1.23.x" + with: + go-version: '1.23.x' - name: Install Go dependencies run: | @@ -51,7 +51,7 @@ jobs: - name: Install firebase tools run: curl -sL firebase.tools | bash - + - name: Run Go tests with Firebase emulator run: firebase emulators:exec --only firestore 'cd ./apps/question-service; go test -v ./tests' @@ -66,11 +66,11 @@ jobs: run: | cd ./apps/frontend cp .env.example .env - + - name: Set up Node.js uses: actions/setup-node@v2 with: - node-version: "22" + node-version: '22' - name: Install pnpm run: npm i -g pnpm @@ -85,38 +85,160 @@ jobs: cd ./apps/frontend pnpm unit-test - test-webdriver-working: + test-docker-compose: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Docker Compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose + + - name: Create Environment Files + env: + QUESTION_SERVICE_URL: ${{ vars.QUESTION_SERVICE_URL }} + USER_SERVICE_URL: ${{ vars.USER_SERVICE_URL }} + MATCHING_SERVICE_URL: ${{ vars.MATCHING_SERVICE_URL }} + HISTORY_SERVICE_URL: ${{ vars.HISTORY_SERVICE_URL }} + SIGNALLING_SERVICE_URL: ${{ vars.SIGNALLING_SERVICE_URL }} + EXECUTION_SERVICE_URL: ${{ vars.EXECUTION_SERVICE_URL }} + JWT_SECRET: ${{ secrets.JWT_SECRET }} + QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} + HISTORY_FIREBASE_CREDENTIAL_PATH: ${{ vars.HISTORY_SERVICE_FIREBASE_CREDENTIAL_PATH }} + EXECUTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.EXECUTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} + DB_CLOUD_URI: ${{ secrets.USER_SERVICE_DB_CLOUD_URI }} + USER_SERVICE_PORT: ${{ vars.USER_SERVICE_PORT }} + MATCHING_SERVICE_PORT: ${{ vars.MATCHING_SERVICE_PORT }} + HISTORY_SERVICE_PORT: ${{ vars.HISTORY_SERVICE_PORT }} + SIGNALLING_SERVICE_PORT: ${{ vars.SIGNALLING_SERVICE_PORT }} + EXECUTION_SERVICE_PORT: ${{ vars.EXECUTION_SERVICE_PORT }} + MATCHING_SERVICE_TIMEOUT: ${{ vars.MATCHING_SERVICE_TIMEOUT }} + REDIS_URL: ${{ vars.REDIS_URL }} + QUESTION_SERVICE_GRPC_URL: ${{ vars.QUESTION_SERVICE_GPRC_URL }} + run: | + cd ./apps/frontend + echo "NEXT_PUBLIC_QUESTION_SERVICE_URL=$QUESTION_SERVICE_URL" >> .env + echo "NEXT_PUBLIC_USER_SERVICE_URL=$USER_SERVICE_URL" >> .env + echo "NEXT_PUBLIC_MATCHING_SERVICE_URL=$MATCHING_SERVICE_URL" >> .env + echo "NEXT_PUBLIC_HISTORY_SERVICE_URL=$HISTORY_SERVICE_URL" >> .env + echo "NEXT_PUBLIC_SIGNALLING_SERVICE_URL=$SIGNALLING_SERVICE_URL" >> .env + echo "NEXT_PUBLIC_EXECUTION_SERVICE_URL=EXECUTION_SERVICE_URL" >> .env + + cd ../question-service + echo "FIREBASE_CREDENTIAL_PATH=$QUESTION_FIREBASE_CREDENTIAL_PATH" >> .env + echo "JWT_SECRET=$JWT_SECRET" >> .env + echo "EXECUTION_SERVICE_URL=$EXECUTION_SERVICE_URL" >> .env + + cd ../user-service + echo "DB_CLOUD_URI=$DB_CLOUD_URI" >> .env + echo "PORT=$USER_SERVICE_PORT" >> .env + echo "JWT_SECRET=$JWT_SECRET" >> .env + + cd ../matching-service + echo "PORT=$MATCHING_SERVICE_PORT" >> .env + echo "MATCH_TIMEOUT=$MATCHING_SERVICE_TIMEOUT" >> .env + echo "JWT_SECRET=$JWT_SECRET" >> .env + echo "REDIS_URL=$REDIS_URL" >> .env + echo "QUESTION_SERVICE_GRPC_URL=$QUESTION_SERVICE_GRPC_URL" >> .env + + cd ../history-service + echo "FIREBASE_CREDENTIAL_PATH=$HISTORY_FIREBASE_CREDENTIAL_PATH" >> .env + echo "PORT=$HISTORY_SERVICE_PORT" >> .env + + cd ../execution-service + echo "FIREBASE_CREDENTIAL_PATH=$EXECUTION_FIREBASE_CREDENTIAL_PATH" >> .env + echo "PORT=$EXECUTION_SERVICE_PORT" >> .env + echo "HISTORY_SERVICE_URL=$HISTORY_SERVICE_URL" >> .env + + cd ../signalling-service + echo "PORT=$SIGNALLING_SERVICE_PORT" >> .env + + - name: Create Database Credential Files + env: + QUESTION_FIREBASE_JSON: ${{ secrets.QUESTION_SERVICE_FIREBASE_CREDENTIAL }} + QUESTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.QUESTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} + HISTORY_FIREBASE_JSON: ${{ secrets.HISTORY_SERVICE_FIREBASE_CREDENTIAL }} + HISTORY_FIREBASE_CREDENTIAL_PATH: ${{ vars.HISTORY_SERVICE_FIREBASE_CREDENTIAL_PATH }} + EXECUTION_FIREBASE_JSON: ${{ secrets.EXECUTION_SERVICE_FIREBASE_CREDENTIAL }} + EXECUTION_FIREBASE_CREDENTIAL_PATH: ${{ vars.EXECUTION_SERVICE_FIREBASE_CREDENTIAL_PATH }} + run: | + cd ./apps/question-service + echo "$QUESTION_FIREBASE_JSON" > "./$QUESTION_FIREBASE_CREDENTIAL_PATH" + + cd ../history-service + echo "$HISTORY_FIREBASE_JSON" > "./$HISTORY_FIREBASE_CREDENTIAL_PATH" + + cd ../execution-service + echo "$EXECUTION_FIREBASE_JSON" > "./$EXECUTION_FIREBASE_CREDENTIAL_PATH" + + - name: Build and Run Services + run: | + cd ./apps + docker-compose up --build -d + + - name: Wait for services to be ready + run: sleep 30 + + - name: Install websocat + run: | + sudo wget -qO /usr/local/bin/websocat https://github.com/vi/websocat/releases/latest/download/websocat.x86_64-unknown-linux-musl + sudo chmod a+x /usr/local/bin/websocat + websocat --version + + - name: Run Tests + env: + FRONTEND_URL: ${{ vars.FRONTEND_URL }} + USER_SERVICE_URL: ${{ vars.USER_SERVICE_URL }} + QUESTION_SERVICE_URL: ${{ vars.QUESTION_SERVICE_URL }} + MATCHING_SERVICE_URL: ${{ vars.MATCHING_SERVICE_URL }} + HISTORY_SERVICE_URL: ${{ vars.HISTORY_SERVICE_URL }} + SIGNALLING_SERVICE_URL: ${{ vars.SIGNALLING_SERVICE_URL }} + EXECUTION_SERVICE_URL: ${{ vars.EXECUTION_SERVICE_URL }} + run: | + echo "Testing Question Service..." + curl -sSL -o /dev/null $QUESTION_SERVICE_URL && echo "Question Service is up" + echo "Testing User Service..." + curl -fsSL -o /dev/null $USER_SERVICE_URL && echo "User Service is up" + echo "Testing Frontend..." + curl -fsSL -o /dev/null $FRONTEND_URL && echo "Frontend is up" + echo "Testing History Service..." + curl -fsSL -o /dev/null $HISTORY_SERVICE_URL && echo "History Service is up" + echo "Testing Execution Service..." + curl -fsSL -o /dev/null $EXECUTION_SERVICE_URL && echo "Execution Service is up" + echo "Testing Matching Service..." + if ! (echo "Hello" | websocat $MATCHING_SERVICE_URL); then + echo "WebSocket for Matching Service is not live" + else + echo "WebSocket for Matching Service is live" + fi + # Add in test for matching service in the future + echo "Testing Signalling Service..." + if ! (echo "Hello" | websocat $SIGNALLING_SERVICE_URL); then + echo "WebSocket for Signalling Service is not live" + else + echo "WebSocket for Signalling Service is live" + fi + # We can add more tests here + - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 9.1.4 - + - name: Install dependencies run: | cd ./apps/frontend pnpm i - + - name: Install Chrome WebDriver uses: nanasess/setup-chromedriver@v2 with: chromedriver-version: '130.0.6723.116' - - - name: Install Edge - uses: browser-actions/setup-edge@v1 - with: - edge-version: stable - - - name: Install Geckodriver - uses: browser-actions/setup-geckodriver@latest - + - name: Run Browser Test run: | cd ./apps/frontend - pnpm browser-test -t "webdriver installed correctly" - + pnpm browser-test \ No newline at end of file diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index 46fa946f63..a80c55d645 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -1,60 +1,37 @@ -import { Actions, Browser, Builder, By, Capabilities, Key, until, WebDriver } from "selenium-webdriver" - -import {Options as ChromeOptions} from "selenium-webdriver/chrome" -import {Options as EdgeOptions} from "selenium-webdriver/edge" -import {Options as FirefoxOptions} from "selenium-webdriver/firefox" +import { Actions, Browser, Builder, By, Key, until, WebDriver } from "selenium-webdriver" +import Chrome from "selenium-webdriver/chrome" const URL = 'http://localhost:3000/'; const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjk5OTk5OTk5OTk5fQ.Z4_FVGQ5lIcouP3m4YLMr6pGMF17IJFfo2yOTiN58DY" -const CHROME_OPTIONS = new ChromeOptions() - .addArguments("--headless=new") as ChromeOptions; // uncomment locally to see the steps in action -const EDGE_OPTIONS = new EdgeOptions() - .setBinaryPath("/opt/hostedtoolcache/msedge/stable/x64/msedge") // need to point to the correct path - .addArguments("--headless=new") as EdgeOptions; - -const FIREFOX_OPTIONS = new FirefoxOptions() - .addArguments("--headless") as FirefoxOptions; - -const builder = new Builder() - .setChromeOptions(CHROME_OPTIONS) - .setEdgeOptions(EDGE_OPTIONS) - .setFirefoxOptions(FIREFOX_OPTIONS) - -describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", (browser) => { +describe("chrome browser", () => { + const options = new Chrome.Options() + .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action + const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); let driver: WebDriver; - beforeAll(() => { - const cap = new Capabilities().setBrowserName(browser) - builder.withCapabilities(cap); - }) beforeEach(async () => { - console.log(browser + ": building..."); driver = await builder.build(); - console.log(browser + ": built"); - }, 10000) + }) afterEach(async () => { - if (driver) { - await driver.quit(); - } + await driver.quit(); }) - describe("webdriver installed correctly", () => { + describe("chrome webdriver installed correctly", () => { it("does google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); }, 10000); - - it.skip("does another google search", async () => { + it("does another google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); }, 10000); }); - describe.skip("browser-test", () => { + describe("browser-test", () => { it("accesses and login to peerprep", async () => { await driver.get(URL); await driver.wait(until.urlIs(`${URL}login`)); @@ -75,8 +52,7 @@ describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", expect(slogan2).toBe("peers"); }, 10000); }) -}, 20000) - +}) From 4b50754ed2490ab425f5467c49b23a64200b7181 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Tue, 12 Nov 2024 17:35:37 +0800 Subject: [PATCH 35/35] Squashed commit of the following: commit 196329a8a96e5a5742e8e4c733133388719e8b43 Author: Ryan Chia Date: Tue Nov 12 17:25:34 2024 +0800 remove webdriver working workflow commit 1add73da99db880d598f11dd2164d7c9346cdbd1 Author: Ryan Chia Date: Tue Nov 12 17:16:25 2024 +0800 asd commit 974caa60ad0657ddcb2e8c35f3a9136d16901f54 Author: Ryan Chia Date: Tue Nov 12 16:09:05 2024 +0800 asad commit f1e3deb88ffb4d02ea53d77785d1477aaef6e7c9 Merge: 5dbc8a0 77f62db Author: Ryan Chia Date: Tue Nov 12 16:04:54 2024 +0800 Merge branch 'browser-compatibility-tests' into browser-tests commit 5dbc8a083ddd10f7ba2065843e88feea63df9e6e Author: Ryan Chia Date: Tue Nov 12 15:50:20 2024 +0800 asd --- .github/workflows/test.yml | 9 +++- .../__tests__/browser-tests/browser.test.ts | 46 ++++++++++++++----- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 13bcff8e10..06afbd05a0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -237,8 +237,15 @@ jobs: uses: nanasess/setup-chromedriver@v2 with: chromedriver-version: '130.0.6723.116' + - name: Install Edge + uses: browser-actions/setup-edge@v1 + with: + edge-version: stable + - name: Install Geckodriver + uses: browser-actions/setup-geckodriver@latest + - name: Run Browser Test run: | cd ./apps/frontend - pnpm browser-test \ No newline at end of file + pnpm browser-test diff --git a/apps/frontend/__tests__/browser-tests/browser.test.ts b/apps/frontend/__tests__/browser-tests/browser.test.ts index a80c55d645..145c036b81 100644 --- a/apps/frontend/__tests__/browser-tests/browser.test.ts +++ b/apps/frontend/__tests__/browser-tests/browser.test.ts @@ -1,30 +1,53 @@ -import { Actions, Browser, Builder, By, Key, until, WebDriver } from "selenium-webdriver" +import { Actions, Browser, Builder, By, Capabilities, Key, until, WebDriver } from "selenium-webdriver" + +import {Options as ChromeOptions} from "selenium-webdriver/chrome" +import {Options as EdgeOptions} from "selenium-webdriver/edge" +import {Options as FirefoxOptions} from "selenium-webdriver/firefox" -import Chrome from "selenium-webdriver/chrome" const URL = 'http://localhost:3000/'; const ETERNAL_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjk5OTk5OTk5OTk5fQ.Z4_FVGQ5lIcouP3m4YLMr6pGMF17IJFfo2yOTiN58DY" -describe("chrome browser", () => { - const options = new Chrome.Options() - .addArguments("--headless=new") as Chrome.Options; // uncomment locally to see the steps in action - const builder = new Builder().forBrowser(Browser.CHROME).setChromeOptions(options); +const CHROME_OPTIONS = new ChromeOptions() + .addArguments("--headless=new") as ChromeOptions; // uncomment locally to see the steps in action +const EDGE_OPTIONS = new EdgeOptions() + .setBinaryPath("/opt/hostedtoolcache/msedge/stable/x64/msedge") // need to point to the correct path + .addArguments("--headless=new") as EdgeOptions; + +const FIREFOX_OPTIONS = new FirefoxOptions() + .addArguments("--headless") as FirefoxOptions; + +const builder = new Builder() + .setChromeOptions(CHROME_OPTIONS) + .setEdgeOptions(EDGE_OPTIONS) + .setFirefoxOptions(FIREFOX_OPTIONS) + +describe.each([Browser.CHROME, Browser.EDGE, Browser.FIREFOX])("%s driver test", (browser) => { let driver: WebDriver; + beforeAll(() => { + const cap = new Capabilities().setBrowserName(browser) + builder.withCapabilities(cap); + }) beforeEach(async () => { + console.log(browser + ": building..."); driver = await builder.build(); - }) + console.log(browser + ": built"); + }, 20000) afterEach(async () => { - await driver.quit(); + if (driver) { + await driver.quit(); + } }) - describe("chrome webdriver installed correctly", () => { + describe("webdriver installed correctly", () => { it("does google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); }, 10000); - it("does another google search", async () => { + + it.skip("does another google search", async () => { await driver.get('http://www.google.com'); await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN); await driver.wait(until.titleIs('webdriver - Google Search'), 1000); @@ -52,7 +75,8 @@ describe("chrome browser", () => { expect(slogan2).toBe("peers"); }, 10000); }) -}) +}, 60000) +