From 324463e3b1ae0812202668ebeacdd1f13c4b7b64 Mon Sep 17 00:00:00 2001 From: Ryan Chia Date: Wed, 6 Nov 2024 01:33:41 +0800 Subject: [PATCH 01/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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/37] 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) + From 9b0c302d535c0987db0922e2d6cc0960ac61560d Mon Sep 17 00:00:00 2001 From: tituschewxj Date: Tue, 12 Nov 2024 21:20:47 +0800 Subject: [PATCH 36/37] fix(frontend): :bug: remove modifiability of username Removes the ability to change username, which fixes the problem in the submission history, as records are queried based on username. This design also is more consistent for users as their matched users usernames in their history remains consistent. --- apps/frontend/src/app/profile/page.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/frontend/src/app/profile/page.tsx b/apps/frontend/src/app/profile/page.tsx index 22b616bed8..424da4e9d0 100644 --- a/apps/frontend/src/app/profile/page.tsx +++ b/apps/frontend/src/app/profile/page.tsx @@ -4,17 +4,17 @@ import { Avatar, Button, Col, - Divider, Form, Input, Layout, message, Row, + Tooltip, } from "antd"; import { Content } from "antd/es/layout/layout"; import "./styles.scss"; import { EditOutlined, SaveOutlined } from "@ant-design/icons"; -import { useEffect, useState, useLayoutEffect } from "react"; +import { useEffect, useState } from "react"; import { UpdateUser, ValidateUser, @@ -117,14 +117,14 @@ const ProfilePage = (props: ProfilePageProps): JSX.Element => { - + @@ -144,7 +144,11 @@ const ProfilePage = (props: ProfilePageProps): JSX.Element => { - + Date: Wed, 13 Nov 2024 18:44:13 +0800 Subject: [PATCH 37/37] Add session status tooltip --- apps/frontend/src/app/collaboration/[id]/page.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/frontend/src/app/collaboration/[id]/page.tsx b/apps/frontend/src/app/collaboration/[id]/page.tsx index 739eac08a6..0eb9721482 100644 --- a/apps/frontend/src/app/collaboration/[id]/page.tsx +++ b/apps/frontend/src/app/collaboration/[id]/page.tsx @@ -12,6 +12,7 @@ import { Tag, Typography, Spin, + Tooltip, } from "antd"; import { Content } from "antd/es/layout/layout"; import "./styles.scss"; @@ -492,7 +493,9 @@ export default function CollaborationPage(props: CollaborationProps) { /> )}
- + + +