From e75a52128474e1da22c74dd9ec032249ab6f6fda Mon Sep 17 00:00:00 2001 From: Aaro Koivukangas Date: Sun, 9 Aug 2026 01:01:38 +0300 Subject: [PATCH] [RIP][Cypress] Wave goodbye to cypress o7, you will not be missed --- .eslintrc.json | 1 - .github/actions/test/e2e/action.yaml | 53 - .github/workflows/pull_request.yaml | 2 - .github/workflows/staging.yaml | 2 - .husky/pre-commit | 2 +- .oxlintrc.json | 22 - README.md | 1 - cypress.config.js | 29 - cypress/e2e/Course_statistics.js | 1271 ------------------- cypress/e2e/Custom_population.js | 192 --- cypress/e2e/Degree_programme_overview.js | 922 -------------- cypress/e2e/Faculty_statistics.js | 287 ----- cypress/e2e/Filters.js | 468 ------- cypress/e2e/Language_center.js | 89 -- cypress/e2e/Population_statistics.js | 443 ------- cypress/e2e/Routes.js | 85 -- cypress/e2e/Students.js | 294 ----- cypress/e2e/Study_guidance_groups.js | 164 --- cypress/e2e/Teachers.js | 64 - cypress/e2e/University.js | 101 -- cypress/fixtures/completedCoursesData.json | 4 - cypress/fixtures/customPopulations.json | 4 - cypress/fixtures/openUniPopulation.json | 4 - cypress/fixtures/studyGuidanceGroups.json | 28 - cypress/plugins/index.js | 34 - cypress/support/commands.js | 198 --- cypress/support/e2e.js | 21 - package-lock.json | 1276 +------------------- package.json | 7 - 29 files changed, 9 insertions(+), 6059 deletions(-) delete mode 100644 .github/actions/test/e2e/action.yaml delete mode 100644 cypress.config.js delete mode 100644 cypress/e2e/Course_statistics.js delete mode 100644 cypress/e2e/Custom_population.js delete mode 100644 cypress/e2e/Degree_programme_overview.js delete mode 100644 cypress/e2e/Faculty_statistics.js delete mode 100644 cypress/e2e/Filters.js delete mode 100644 cypress/e2e/Language_center.js delete mode 100644 cypress/e2e/Population_statistics.js delete mode 100644 cypress/e2e/Routes.js delete mode 100644 cypress/e2e/Students.js delete mode 100644 cypress/e2e/Study_guidance_groups.js delete mode 100644 cypress/e2e/Teachers.js delete mode 100644 cypress/e2e/University.js delete mode 100644 cypress/fixtures/completedCoursesData.json delete mode 100644 cypress/fixtures/customPopulations.json delete mode 100644 cypress/fixtures/openUniPopulation.json delete mode 100644 cypress/fixtures/studyGuidanceGroups.json delete mode 100644 cypress/plugins/index.js delete mode 100644 cypress/support/commands.js delete mode 100644 cypress/support/e2e.js diff --git a/.eslintrc.json b/.eslintrc.json index d415a6d28..5193a2f81 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,7 +8,6 @@ "**/coverage/**", "nyc-config.cjs", ".lintstagedrc.mjs", - "cypress.config.js", "playwright/**/*.js" ] } diff --git a/.github/actions/test/e2e/action.yaml b/.github/actions/test/e2e/action.yaml deleted file mode 100644 index d7994575f..000000000 --- a/.github/actions/test/e2e/action.yaml +++ /dev/null @@ -1,53 +0,0 @@ -name: 'Run tests' -description: 'Runs Cypress tests for individual spec' - -inputs: - username: - required: true - description: 'Toska registry username' - password: - required: true - description: 'Toska registry password' - spec: - required: true - description: 'Path to Cypress file' - test_name: - required: true - description: 'Name of the test' - -runs: - using: composite - steps: - - name: 'Login to toska Docker registry' - uses: docker/login-action@v4 - with: - registry: registry-toska.ext.ocp-prod-0.k8s.it.helsinki.fi - username: ${{ inputs.username }} - password: ${{ inputs.password }} - - - name: 'Run services, pull rest of the needed images' - shell: bash - run: docker compose --file docker-compose.ci.yml --profile oodikone up --detach --quiet-pull - - - name: Run Cypress inside docker container - shell: bash - # Permission errors? See: https://github.com/cypress-io/cypress-docker-images/blob/master/examples/included-as-non-root/README.md#run-as-non-root - run: | - docker run --user node --rm -v $PWD:/e2e -w /e2e --add-host host.docker.internal:host-gateway -e CYPRESS_VIDEO -e CYPRESS_baseUrl=http://host.docker.internal:1337 --entrypoint cypress cypress/included:15.18.1 run --browser firefox --spec ${{ inputs.spec }} - - - name: 'Upload video if tests fail' - uses: actions/upload-artifact@v7 - if: failure() - with: - name: 'Cypress videos - ${{ inputs.test_name }}' - path: /tmp/cypress/videos/* - retention-days: 7 - - - name: 'Print logs on failure' - shell: bash - if: failure() - run: npm run logs:ci && sleep 15 - - - name: Teardown containers started by compose - if: always() - uses: ./.github/actions/teardown diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index f59e26f2f..e41e1afac 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -13,8 +13,6 @@ on: - 'docker-compose.ci.yml' - 'docker-compose.test.yml' - 'package*.json' - - 'cypress/**' - - 'cypress.config.json' jobs: test: diff --git a/.github/workflows/staging.yaml b/.github/workflows/staging.yaml index e5f4d4506..9466cce7f 100644 --- a/.github/workflows/staging.yaml +++ b/.github/workflows/staging.yaml @@ -13,8 +13,6 @@ on: - 'docker-compose.ci.yml' - 'docker-compose.test.yml' - 'package*.json' - - 'cypress/**' - - 'cypress.config.json' jobs: test: diff --git a/.husky/pre-commit b/.husky/pre-commit index b2e0cdb0d..e49dbc086 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,6 +1,6 @@ npx lint-staged -if git grep -qE --cached "(it|describe)\.only" $(git diff --cached --name-only --diff-filter=ACMR | xargs) ./cypress; then +if git grep -qE --cached "(it|describe)\.only" $(git diff --cached --name-only --diff-filter=ACMR | xargs); then echo "\e[0;31mDo not commit .only-tests." exit 1 else diff --git a/.oxlintrc.json b/.oxlintrc.json index b0c6be6ae..8f64dc957 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -45,8 +45,6 @@ "**/coverage/**", "nyc-config.cjs", ".lintstagedrc.mjs", - "cypress.config.js", - "cypress/**/*.js", "playwright/**/*.js", "playwright.config.ts" ], @@ -348,26 +346,6 @@ }, "plugins": ["react"] }, - { - "files": ["cypress/**/*.js"], - "rules": { - "cypress/no-assigning-return-values": "error", - "cypress/no-unnecessary-waiting": "error", - "cypress/no-async-tests": "error", - "cypress/unsafe-to-chain-command": "error" - }, - "jsPlugins": ["eslint-plugin-cypress"], - "globals": { - "cy": "readonly", - "Cypress": "readonly", - "expect": "readonly", - "assert": "readonly", - "chai": "readonly" - }, - "env": { - "mocha": true - } - }, { "files": ["services/backend/tests/**/*.ts"], "rules": { diff --git a/README.md b/README.md index 60bfff731..5f37f669a 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,6 @@ Playwright - Run all migrated specs with `npm run playwright`. - Run headed mode with `npm run playwright:headed`. - Open UI mode with `npm run playwright:ui`. -- The migration from Cypress was done with an automated converter. The generated files are a baseline and still need manual cleanup in places where `cy.*` logic is left over. Continuous integration (CI) works with Github actions and is defined in workflow files in `.github/workflows` folder: diff --git a/cypress.config.js b/cypress.config.js deleted file mode 100644 index 0d868f014..000000000 --- a/cypress.config.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable import-x/no-extraneous-dependencies */ -/* eslint-disable import-x/no-default-export */ -const { defineConfig } = require('cypress') - -module.exports = defineConfig({ - projectId: 'c3jsph', - - // Fixes Github <-> Cypress permission errors in CI - downloadsFolder: '/tmp/cypress/downloads', - screenshotsFolder: '/tmp/cypress/screenshots', - videosFolder: '/tmp/cypress/videos', - video: true, - - defaultCommandTimeout: 30000, - requestTimeout: 30000, - videoCompression: false, - viewportWidth: 1920, - viewportHeight: 1080, - e2e: { - // We've imported your old cypress plugins here. - // You may want to clean this up later by importing these. - setupNodeEvents(on, config) { - require('./cypress/plugins/index.js')(on, config) - return config - }, - baseUrl: 'http://localhost:3000', - specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}', - }, -}) diff --git a/cypress/e2e/Course_statistics.js b/cypress/e2e/Course_statistics.js deleted file mode 100644 index 74e6efa04..000000000 --- a/cypress/e2e/Course_statistics.js +++ /dev/null @@ -1,1271 +0,0 @@ -/// - -// TODO: Test the pass rate and grade distribution charts and the Show relative toggle -// TODO: Test Export to Excel (assert that the file was downloaded, see other tests for examples) -// TODO: Test population link status (should be disabled for empty rows) -// TODO: Test Enrolled, no grade being null for years before Sisu era (currently displays 0 for empty) - -const checkGradeTable = gradesTableContents => { - cy.cs('Grade distribution') - .parent() - .then($el => { - if (!$el.hasClass('Mui-expanded')) { - cy.cs('Grade distribution').click() - } - - cy.cs('Grade distribution-data') - .get('table > tbody') - .first() - .within(() => { - gradesTableContents.forEach((values, trIndex) => { - cy.get('tr') - .eq(trIndex) - .within(() => { - values.forEach((value, tdIndex) => { - if (value === null) return - cy.get('td').eq(tdIndex).contains(value) - }) - }) - }) - cy.get('tr').should('have.length', gradesTableContents.length) - }) - }) -} - -const checkTableContents = contents => { - cy.get('table tbody').scrollIntoView() - cy.get('table tbody').within(() => { - contents.forEach((values, trIndex) => { - cy.get('tr') - .eq(trIndex) - .within(() => { - values.forEach((value, tdIndex) => { - if (value === null) return - cy.get('td').eq(tdIndex).contains(value) - }) - }) - }) - cy.get('tr').should('have.length', contents.length) - }) -} - -const toggleShowGrades = () => { - cy.cs('gradeToggle', { force: true }).click({ force: true }) -} - -const toggleSeparateBySemesters = () => { - cy.cs('separateToggle', { force: true }).click({ force: true }) -} - -const openStudentsTab = () => { - cy.cs('StudentsTab').click() -} - -const openAttemptsTab = () => { - cy.cs('AttemptsTab').click() -} - -const searchByCourseName = courseName => { - cy.get("input[placeholder='Search by course name']").type(courseName) -} - -const searchByCourseCode = courseCode => { - cy.get("input[placeholder='Search by course code']").type(courseCode) -} - -const clickNewQueryButton = () => { - cy.cs('NewQueryButton').click() -} - -const selectFromYear = year => { - cy.cs('FromYearSelector').click() - cy.cs(`FromYearSelectorOption${year}`).click() -} - -const openSummaryTab = () => { - cy.cs('SummaryTab').click() -} - -const clickAway = () => { - cy.get('body').click(0, 0) -} - -const getCourseSearchHooksForSingleYear = code => { - cy.intercept({ - pathname: '/api/coursesmulti', - query: { code }, - }).as('courses') - - cy.intercept({ - pathname: '/api/courseyearlystats', - query: { 'codes[]': code }, - }).as('yearlystats') - - cy.intercept({ - pathname: '/api/populationstatisticsbycourse', - }).as('coursestats') -} - -describe('Basic user', () => { - beforeEach(() => { - cy.init('/coursestatistics', 'basic') - cy.url().should('include', '/coursestatistics') - }) - - it('Search should work on consecutive searches', () => { - const coursecode1 = 'TKT20003' - getCourseSearchHooksForSingleYear(coursecode1) - - searchByCourseCode(coursecode1) - cy.wait('@courses').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.cs(`course-${coursecode1}`).click() - - cy.wait('@yearlystats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.url().should('contain', `courseCodes=%5B%22${coursecode1}%22%5D`) - - cy.contains('Show population').should('be.enabled') - cy.contains('Show population').click() - - cy.wait('@coursestats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.contains(coursecode1) - - cy.contains('Courses').click() - - const coursecode2 = 'TKT20001' - getCourseSearchHooksForSingleYear(coursecode2) - - searchByCourseCode(coursecode2) - cy.wait('@courses').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.cs(`course-${coursecode2}`).click() - - cy.wait('@yearlystats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.url().should('contain', `courseCodes=%5B%22${coursecode2}%22%5D`) - - cy.contains('Show population').should('be.enabled') - cy.contains('Show population').click() - - cy.wait('@coursestats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.contains(coursecode2) - }) - - describe('Course table can show non-standard grades', () => { - it('Course table can show HT-TT grade scales', () => { - const coursecode = 'KK-RUKIRJ' - getCourseSearchHooksForSingleYear(coursecode) - - searchByCourseCode(coursecode) - cy.wait('@courses').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.cs(`course-${coursecode}`).click() - - cy.wait('@yearlystats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.url().should('contain', `courseCodes=%5B%22${coursecode}%22%5D`) - - selectFromYear('2019-2020') - cy.contains('Show population').should('be.enabled') - cy.contains('Show population').click() - - cy.wait('@coursestats').its('response.statusCode').should('be.oneOf', [200, 304]) - - const gradesTableContents = [ - [null, 'TT', 179], - [null, 'No grade', 10], - [null, 'HT', 179], - ] - checkGradeTable(gradesTableContents) - }) - - it("Course table can show old master's thesis grade scales", () => { - const coursecode = '50131' - getCourseSearchHooksForSingleYear(coursecode) - - searchByCourseCode(coursecode) - cy.wait('@courses').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.cs(`course-${coursecode}`).click() - - cy.wait('@yearlystats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.url().should('contain', `courseCodes=%5B%22${coursecode}%22%5D`) - - cy.contains('50131') // Pro gradu -tutkielma tietojenkäsittelytieteessä - cy.contains('Show population').should('be.enabled') - cy.contains('Show population').click() - - cy.wait('@coursestats').its('response.statusCode').should('be.oneOf', [200, 304]) - - cy.contains('Pro gradu -tutkielma tietojenkäsittelytieteessä') - cy.contains('Class of 2007-2020, 10 students') - cy.contains('Include substitutions, Open and normal') - - cy.contains('Showing 10 out of 10 students') - - const gradesTableContents = [ - [null, 'NSLA', 1], - [null, 'L', 3], - [null, 'ECLA', 5], - [null, 'CL', 1], - ] - checkGradeTable(gradesTableContents) - }) - - it('Shows correct statistics for courses with scale passed-failed', () => { - const coursecode = '200012' - getCourseSearchHooksForSingleYear(coursecode) - - searchByCourseCode(coursecode) - cy.wait('@courses').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.cs(`course-${coursecode}`).click() - - cy.wait('@yearlystats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.url().should('contain', `courseCodes=%5B%22${coursecode}%22%5D`) - - cy.contains('ON-310') // Tieteellisen kirjoittamisen seminaarin alkuopetus: Tieteellisen kirjallisen työn ja tiedonhankinnan perustaidot - cy.contains('200012') // Tieteellisen kirjallisen työn ja tiedonhankinnan perustaidot - cy.contains('Show population').should('be.enabled') - cy.contains('Show population').click() - - cy.wait('@coursestats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.contains('Tieteellisen kirjallisen työn ja tiedonhankinnan perustaidot') - cy.contains('Class of 2011-2018, 4 students') - cy.contains('Include substitutions, Open and normal') - cy.contains('Showing 4 out of 4 students') - - const gradesTableContents = [ - [null, 'Hyv.', 3], - [null, 'Hyl.', 1], - ] - checkGradeTable(gradesTableContents) - }) - }) - - describe('Course mappings work', () => { - it('Searching single course having substitution mappings shows course statistics', () => { - const coursecode = 'TKT20001' - getCourseSearchHooksForSingleYear(coursecode) - - searchByCourseCode(coursecode) - cy.wait('@courses').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.cs(`course-${coursecode}`).click() - - cy.wait('@yearlystats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.url().should('contain', `courseCodes=%5B%22${coursecode}%22%5D`) - - cy.contains('Tietorakenteet ja algoritmit') - cy.contains('TKT20001') - cy.contains('58131') - - openStudentsTab() - cy.contains('svg', 'Pass rate') - - openAttemptsTab() - cy.contains('svg', 'Pass rate') - - clickNewQueryButton() - cy.contains('Search for courses') - }) - - it('Searching multiple courses having substitution mappings shows course statistics', () => { - cy.intercept({ - pathname: '/api/coursesmulti', - query: { code: 'TKT' }, - }).as('courses') - - cy.intercept({ - pathname: '/api/courseyearlystats', - query: { 'codes[]': 'TKT20001', 'codes[]': 'TKT10002' }, - }).as('yearlystats') - - cy.intercept({ - pathname: '/api/populationstatisticsbycourse', - }).as('coursestats') - - cy.cs('select-multiple-courses-toggle').should('not.have.class', 'Mui-checked') - cy.cs('select-multiple-courses-toggle').click() - cy.cs('select-multiple-courses-toggle').should('have.class', 'Mui-checked') - - searchByCourseCode('TKT') - cy.wait('@courses').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.cs(`course-TKT20001`).click() - cy.cs(`course-TKT10002`).click() - - cy.contains('Fetch statistics').should('be.enabled') - cy.contains('Fetch statistics').click() - - cy.wait('@yearlystats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.url().should('contain', 'courseCodes=%5B%22TKT10002%22%2C%22TKT20001%22%5D') - - openSummaryTab() - cy.contains('Tietorakenteet ja algoritmit').click() - cy.contains('TKT10002').should('exist') - cy.contains('TKT20001').should('exist') - cy.contains('58131').should('not.exist') - - openSummaryTab() - cy.contains('Ohjelmoinnin perusteet').click() - cy.contains('TKT10002').should('exist') - cy.contains('TKT20001').should('exist') - cy.contains('Käyttöjärjestelmät').should('not.exist') - cy.contains('581325').should('not.exist') - openSummaryTab() - }) - }) - - it('On searches with multiple courses, has correct links on the Course tab', () => { - cy.intercept({ - pathname: '/api/coursesmulti', - query: { code: 'BSCS' }, - }).as('courses') - - cy.intercept({ - pathname: '/api/courseyearlystats', - query: { 'codes[]': 'BSCS1003', 'codes[]': 'BSCS1001' }, - }).as('yearlystats') - - cy.intercept({ - pathname: '/api/populationstatisticsbycourse', - }).as('coursestats') - - cy.cs('select-multiple-courses-toggle').should('not.have.class', 'Mui-checked') - cy.cs('select-multiple-courses-toggle').click() - cy.cs('select-multiple-courses-toggle').should('have.class', 'Mui-checked') - - searchByCourseCode('BSCS') - cy.wait('@courses').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.cs(`course-BSCS1003`).click() - cy.cs(`course-BSCS1001`).click() - - cy.contains('Fetch statistics').should('be.enabled') - cy.contains('Fetch statistics').click() - - cy.wait('@yearlystats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.url().should('contain', 'courseCodes=%5B%22BSCS1001%22%2C%22BSCS1003%22%5D') - - cy.cs('course-population-for-2023-2024').click() - cy.contains('Introduction to Programming') - cy.contains('Class of 2023-2024') - cy.contains('Include substitutions, Open and normal') - - // NOTE: These should also have `cy.intercept`s. - // The calls should be either cached or cheap so this is only - // necessary if the test is flaky. - cy.go('back') - cy.cs('CourseSelector').click() - cy.cs('CourseSelectorOptionBSCS1003').click() - // Check the link has updated correctly - cy.cs('course-population-for-2022-2023').invoke('attr', 'href').should('include', 'BSCS1003') - cy.cs('course-population-for-2022-2023').click() - cy.contains('Data Structures and Algorithms') - cy.contains('Class of 2022-2023') - cy.contains('Include substitutions, Open and normal') - }) - - it('Searching course by name displays right courses', () => { - cy.contains('Search for courses') - searchByCourseName('tietokantojen perusteet') - - cy.contains('Tietokantojen perusteet') - cy.cs(`course-TKT10004`).click() - - cy.contains('Search for courses').should('not.exist') - - cy.contains('TKT10004') // Tietokantojen perusteet - cy.contains('AYTKT10004') // Avoin yo: Tietokantojen perusteet - cy.contains('BSCS2001') // Introduction to Databases - cy.contains('581328') // Tietokantojen perusteet - cy.contains('A581328') // Avoin yo: Tietokantojen perusteet - clickNewQueryButton() - cy.contains('Please enter at least 5 characters for course name or 2 characters for course code.') - }) - - it('Searching course by name displays right courses, 10 credit courses', { retries: 2 }, () => { - cy.contains('Search for courses') - searchByCourseName('tietorakenteet ja algoritmit') - cy.contains('Tietorakenteet ja algoritmit') - cy.cs(`course-TKT20001`).click() - cy.contains('Search for courses').should('not.exist') - - cy.contains('TKT20001') // Tietorakenteet ja algoritmit - cy.contains('AYTKT20001') // Avoin yo: Tietorakenteet ja algoritmit - cy.contains('BSCS1003') // Data Structures and Algorithms - cy.contains('58131') // Tietorakenteet - clickNewQueryButton() - cy.contains('Please enter at least 5 characters for course name or 2 characters for course code.') - searchByCourseName('tietorakenteet ja algoritmit') - cy.cs(`course-TKT20001`).click() - - cy.contains('Search for courses').should('not.exist') - cy.contains('TKT20001') // Tietorakenteet ja algoritmit - cy.contains('AYTKT20001') // Avoin yo: Tietorakenteet ja algoritmit - cy.contains('BSCS1003') // Data Structures and Algorithms - cy.contains('58131') // Tietorakenteet - }) - - it('"Select all search results" button is not showing unless "Select multiple courses" toggle is on', () => { - cy.contains('Search for courses') - searchByCourseCode('TKT') - cy.cs('select-multiple-courses-toggle').should('not.have.class', 'Mui-checked') - cy.contains('Select all search results').should('not.exist') - cy.cs('select-multiple-courses-toggle').click() - cy.cs('select-multiple-courses-toggle').should('have.class', 'Mui-checked') - cy.contains('Select all search results') - }) - - it('Provider organization select works', () => { - cy.contains('Search for courses') - searchByCourseName('tietokantojen perusteet') - - cy.cs(`course-TKT10004`).click() - cy.contains('Search for courses').should('not.exist') - - cy.contains('TKT10004') // Tietokantojen perusteet - cy.contains('AYTKT10004') // Avoin yo: Tietokantojen perusteet - cy.contains('BSCS2001') // Introduction to Databases - cy.contains('581328') // Tietokantojen perusteet - cy.contains('A581328') // Avoin yo: Tietokantojen perusteet - - cy.cs('ProviderOrganizationSelect').click() - cy.cs('ProviderOrganizationSelectOptionBoth').should('have.class', 'Mui-selected') - cy.cs('ProviderOrganizationSelectOptionRegular').should('not.have.class', 'Mui-selected') - cy.cs('ProviderOrganizationSelectOptionOpen').should('not.have.class', 'Mui-selected') - - cy.cs('ProviderOrganizationSelectOptionRegular').click() - cy.cs('ProviderOrganizationSelectOptionBoth').should('not.have.class', 'Mui-selected') - cy.cs('ProviderOrganizationSelectOptionRegular').should('have.class', 'Mui-selected') - cy.cs('ProviderOrganizationSelectOptionOpen').should('not.have.class', 'Mui-selected') - - cy.cs('ProviderOrganizationSelect').click() - cy.cs('ProviderOrganizationSelectOptionOpen').click() - cy.cs('ProviderOrganizationSelectOptionBoth').should('not.have.class', 'Mui-selected') - cy.cs('ProviderOrganizationSelectOptionRegular').should('not.have.class', 'Mui-selected') - cy.cs('ProviderOrganizationSelectOptionOpen').should('have.class', 'Mui-selected') - }) - - describe('Course populations', () => { - it('Can find course population', () => { - cy.contains('Search for courses') - searchByCourseCode('TKT20003') - cy.contains('tr', 'TKT20003').click() - cy.contains('TKT20003') // Käyttöjärjestelmät - cy.contains('582219') // Käyttöjärjestelmät - cy.cs('course-population-for-2020-2021').click() - - cy.contains('Käyttöjärjestelmät') - cy.contains('Class of 2020-2021, 19 students') - cy.contains('Include substitutions, Open and normal') - - cy.contains('TKT20003') - - cy.contains('Students (19)').click() - cy.contains('394776') - cy.contains('416369') - }) - - it('Population of course shows grades for each student', () => { - searchByCourseCode('TKT20001') - cy.cs(`course-TKT20001`).click() - cy.contains('TKT20001') // Tietorakenteet ja algoritmit - cy.contains('AYTKT20001') // Avoin yo: Tietorakenteet ja algoritmit - cy.contains('BSCS1003') // Data Structures and Algorithms - cy.contains('58131') // Tietorakenteet - cy.cs('course-population-for-2019-2020').click() - - cy.contains('Tietorakenteet ja algoritmit') - cy.contains('Class of 2019-2020, 33 students') - cy.contains('Include substitutions, Open and normal') - - cy.contains('Students (33)').click() - cy.contains('td', '394776').siblings().eq(2).contains('3') - cy.contains('td', '497388').siblings().eq(2).contains('2') - }) - - it("In 'Course population' view, student numbers of students that the user isn't allowed to see are hidden", () => { - searchByCourseCode('TKT20001') - cy.cs(`course-TKT20001`).click() - cy.contains('TKT20001') // Tietorakenteet ja algoritmit - cy.contains('AYTKT20001') // Avoin yo: Tietorakenteet ja algoritmit - cy.contains('BSCS1003') // Data Structures and Algorithms - cy.contains('58131') // Tietorakenteet - cy.cs('course-population-for-2019-2020').click() - - cy.contains('Tietorakenteet ja algoritmit') - cy.contains('Class of 2019-2020, 33 students') - cy.contains('Include substitutions, Open and normal') - - cy.contains('Students (33)').click() - cy.get('table tbody td').filter(':contains("Hidden")').should('have.length', 9) - }) - }) - - it('Language distribution is correct', () => { - searchByCourseCode('TKT20003') - cy.cs(`course-TKT20003`).click() - cy.contains('TKT20003') // Käyttöjärjestelmät - cy.contains('582219') // Käyttöjärjestelmät - cy.cs('course-population-for-2021-2022').click() - - cy.contains('Käyttöjärjestelmät') - cy.contains('Class of 2021-2022') - cy.contains('Include substitutions, Open and normal') - - cy.contains('Language distribution').click() - cy.contains('td', 'finnish').siblings().eq(0).contains('5') - cy.contains('td', 'english').siblings().eq(0).contains('2') - }) - - describe('Single course stats', () => { - describe('Combine substitutions off', () => { - beforeEach(() => { - cy.url().should('include', '/coursestatistics') - cy.contains('Search for courses') - cy.cs('combine-substitutions-toggle').should('have.class', 'Mui-checked').click() - cy.cs('combine-substitutions-toggle').should('not.have.class', 'Mui-checked') - searchByCourseCode('TKT10002') - cy.cs(`course-TKT10002`).click() - cy.contains('Search for courses').should('not.exist') - cy.contains('TKT10002') // Ohjelmoinnin perusteet - }) - - it('Time range', () => { - cy.cs('FromYearSelector').click() - cy.cs('FromYearSelectorOption2016-2017').should('have.class', 'Mui-selected') - cy.get('[data-cy^="FromYearSelectorOption"]').should('have.length', 8) - clickAway() - - cy.cs('ToYearSelector').click() - cy.cs('ToYearSelectorOption2023-2024').should('have.class', 'Mui-selected') - cy.get('[data-cy^="ToYearSelectorOption"]').should('have.length', 8) - clickAway() - - cy.contains('Show population').should('be.enabled') - }) - - // TODO: Writing these as backend api tests - describe.skip('Students tab', () => { - describe('Info boxes', () => { - it('Student statistics table', () => { - cy.cs('StudentStatistics-info-box-button').click() - cy.cs('StudentStatistics-info-box-content').contains('Table - Students') - }) - - it('Pass rate', () => { - cy.cs('PassRateStudents-info-box-button').click() - cy.cs('PassRateStudents-info-box-content').contains('Pass rate - Students') - }) - - it('Grade distribution', () => { - toggleShowGrades() - cy.cs('GradeDistribution-info-box-button').click() - cy.cs('GradeDistribution-info-box-content').contains('Grade distribution') - }) - }) - - it('Show grades off, Separate by semesters off', () => { - const tableContents = [ - // [Time, Total students, Passed, Failed, Enrolled no grade, Pass rate, Fail rate] - ['Total', 183, 140, 6, 37, '76.50 %', '23.50 %'], - ['2023-2024', 7, 1, 0, 6, '14.29 %', '85.71 %'], - ['2022-2023', 32, 26, 0, 6, '81.25 %', '18.75 %'], - ['2021-2022', 39, 14, 0, 25, '35.90 %', '64.10 %'], - ['2020-2021', 21, 21, 0, null, '100.00 %', '0.00 %'], - ['2019-2020', 28, 28, 0, null, '100.00 %', '0.00 %'], - ['2018-2019', 29, 27, 2, null, '93.10 %', '6.90 %'], - ['2017-2018', 26, 22, 4, null, '84.62 %', '15.38 %'], - ['2016-2017', 1, 1, 0, null, '100.00 %', '0.00 %'], - ] - checkTableContents(tableContents) - }) - - it('Show grades off, Separate by semesters on', () => { - const tableContents = [ - // [Time, Total students, Passed, Failed, Enrolled no grade, Pass rate, Fail rate] - ['Total', 185, 140, 6, 39, '75.68 %', '24.32 %'], - ['Syksy 2023', 7, 1, 0, 6, '14.29 %', '85.71 %'], - ['Kevät 2023', 10, 9, 0, 1, '90.00 %', '10.00 %'], - ['Syksy 2022', 22, 17, 0, 5, '77.27 %', '22.73 %'], - ['Kevät 2022', 26, 9, 0, 17, '34.62 %', '65.38 %'], - ['Syksy 2021', 15, 5, 0, 10, '33.33 %', '66.67 %'], - ['Kevät 2021', 3, 3, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2020', 18, 18, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2020', 3, 3, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2019', 25, 25, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2019', 7, 7, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2018', 22, 20, 2, null, '90.91 %', '9.09 %'], - ['Kevät 2018', 18, 14, 4, null, '77.78 %', '22.22 %'], - ['Syksy 2017', 8, 8, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2017', 0, 0, 0, 0, '–', '–'], - ['Syksy 2016', 1, 1, 0, null, '100.00 %', '0.00 %'], - ] - toggleSeparateBySemesters() - checkTableContents(tableContents) - }) - - it('Show grades on, Separate by semesters off', () => { - const tableContents = [ - // [Time, Total students, Failed, 1, 2, 3, 4, 5, Other passed, Enrolled no grade, Pass rate, Fail rate] - ['Total', 183, 6, 3, 8, 5, 24, 99, 1, 37, '76.50 %', '23.50 %'], - ['2023-2024', 7, 0, 0, 0, 0, 0, 1, 0, 6, '14.29 %', '85.71 %'], - ['2022-2023', 32, 0, 0, 0, 0, 6, 20, 0, 6, '81.25 %', '18.75 %'], - ['2021-2022', 39, 0, 0, 0, 0, 2, 12, 0, 25, '35.90 %', '64.10 %'], - ['2020-2021', 21, 0, 0, 1, 0, 2, 17, 1, null, '100.00 %', '0.00 %'], - ['2019-2020', 28, 0, 1, 4, 1, 5, 17, 0, null, '100.00 %', '0.00 %'], - ['2018-2019', 29, 2, 2, 1, 2, 3, 19, 0, null, '93.10 %', '6.90 %'], - ['2017-2018', 26, 4, 0, 2, 2, 5, 13, 0, null, '84.62 %', '15.38 %'], - ['2016-2017', 1, 0, 0, 0, 0, 1, 0, 0, null, '100.00 %', '0.00 %'], - ] - toggleShowGrades() - checkTableContents(tableContents) - }) - - it('Show grades on, Separate by semesters on', () => { - const tableContents = [ - // [Time, Total students, Failed, 1, 2, 3, 4, 5, Other passed, Enrolled no grade, Pass rate, Fail rate] - ['Total', 185, 6, 3, 8, 5, 24, 99, 1, 39, '75.68 %', '24.32 %'], - ['Syksy 2023', 7, 0, 0, 0, 0, 0, 1, 0, 6, '14.29 %', '85.71 %'], - ['Kevät 2023', 10, 0, 0, 0, 0, 3, 6, 0, 1, '90.00 %', '10.00 %'], - ['Syksy 2022', 22, 0, 0, 0, 0, 3, 14, 0, 5, '77.27 %', '22.73 %'], - ['Kevät 2022', 26, 0, 0, 0, 0, 2, 7, 0, 17, '34.62 %', '65.38 %'], - ['Syksy 2021', 15, 0, 0, 0, 0, 0, 5, 0, 10, '33.33 %', '66.67 %'], - ['Kevät 2021', 3, 0, 0, 0, 0, 0, 3, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2020', 18, 0, 0, 1, 0, 2, 14, 1, null, '100.00 %', '0.00 %'], - ['Kevät 2020', 3, 0, 0, 0, 1, 0, 2, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2019', 25, 0, 1, 4, 0, 5, 15, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2019', 7, 0, 0, 0, 1, 1, 5, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2018', 22, 2, 2, 1, 1, 2, 14, 0, null, '90.91 %', '9.09 %'], - ['Kevät 2018', 18, 4, 0, 2, 0, 3, 9, 0, null, '77.78 %', '22.22 %'], - ['Syksy 2017', 8, 0, 0, 0, 2, 2, 4, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2017', 0, 0, 0, 0, 0, 0, 0, 0, 0, '–', '–'], - ['Syksy 2016', 1, 0, 0, 0, 0, 1, 0, 0, null, '100.00 %', '0.00 %'], - ] - toggleShowGrades() - toggleSeparateBySemesters() - checkTableContents(tableContents) - }) - }) - - // TODO: Writing these as backend api tests - describe.skip('Attempts tab', () => { - beforeEach(() => { - openAttemptsTab() - }) - - describe('Info boxes', () => { - it('Attempt statistics table', () => { - cy.cs('AttemptStatistics-info-box-button').click() - cy.cs('AttemptStatistics-info-box-content').contains('Table - Attempts') - }) - - it('Pass rate', () => { - cy.cs('PassRateAttempts-info-box-button').click() - cy.cs('PassRateAttempts-info-box-content').contains('Pass rate - Attempts') - }) - - it('Grade distribution', () => { - toggleShowGrades() - cy.cs('GradeDistribution-info-box-button').click() - cy.cs('GradeDistribution-info-box-content').contains('Grade distribution') - }) - }) - - it('Show grades off, Separate by semesters off', () => { - const tableContents = [ - // [Time, Total attempts, Passed, Failed, Pass rate, Enrollments] - ['Total', 178, 140, 6, '95.89 %', 73], - ['2023-2024', 6, 1, null, '16.67 %', 6], - ['2022-2023', 26, 26, null, '100.00 %', 26], - ['2021-2022', 41, 14, null, '34.15 %', 41], - ['2020-2021', 21, 21, null, '100.00 %', null], - ['2019-2020', 28, 28, null, '100.00 %', null], - ['2018-2019', 29, 27, 2, '93.10 %', null], - ['2017-2018', 26, 22, 4, '84.62 %', null], - ['2016-2017', 1, 1, null, '100.00 %', null], - ] - checkTableContents(tableContents) - }) - - it('Show grades off, Separate by semesters on', () => { - const tableContents = [ - // [Time, Total attempts, Passed, Failed, Pass rate, Enrollments] - ['Total', 178, 140, 6, '95.89 %', 73], - ['Syksy 2023', 6, 1, 0, '16.67 %', 6], - ['Kevät 2023', 11, 9, 0, '81.82 %', 11], - ['Syksy 2022', 15, 17, 0, '100.00 %', 15], - ['Kevät 2022', 29, 9, 0, '31.03 %', 29], - ['Syksy 2021', 12, 5, 0, '41.67 %', 12], - ['Kevät 2021', 3, 3, 0, '100.00 %', null], - ['Syksy 2020', 18, 18, 0, '100.00 %', null], - ['Kevät 2020', 3, 3, 0, '100.00 %', null], - ['Syksy 2019', 25, 25, 0, '100.00 %', null], - ['Kevät 2019', 7, 7, 0, '100.00 %', null], - ['Syksy 2018', 22, 20, 2, '90.91 %', null], - ['Kevät 2018', 18, 14, 4, '77.78 %', null], - ['Syksy 2017', 8, 8, 0, '100.00 %', null], - ['Kevät 2017', 0, 0, 0, '–', 0], - ['Syksy 2016', 1, 1, 0, '100.00 %', null], - ] - toggleSeparateBySemesters() - checkTableContents(tableContents) - }) - - it('Show grades on, Separate by semesters off', () => { - const tableContents = [ - // [Time, Total attempts, 0, 1, 2, 3, 4, 5, Other passed] - ['Total', 178, 6, 3, 8, 5, 24, 99, 1], - ['2023-2024', 6, 0, 0, 0, 0, 0, 1, 0], - ['2022-2023', 26, 0, 0, 0, 0, 6, 20, 0], - ['2021-2022', 41, 0, 0, 0, 0, 2, 12, 0], - ['2020-2021', 21, 0, 0, 1, 0, 2, 17, 1], - ['2019-2020', 28, 0, 1, 4, 1, 5, 17, 0], - ['2018-2019', 29, 2, 2, 1, 2, 3, 19, 0], - ['2017-2018', 26, 4, 0, 2, 2, 5, 13, 0], - ['2016-2017', 1, 0, 0, 0, 0, 1, 0, 0], - ] - toggleShowGrades() - checkTableContents(tableContents) - }) - - it('Show grades on, Separate by semesters on', () => { - const tableContents = [ - // [Time, Total attempts, 0, 1, 2, 3, 4, 5, Other passed] - ['Total', 178, 6, 3, 8, 5, 24, 99, 1], - ['Syksy 2023', 6, 0, 0, 0, 0, 0, 1, 0], - ['Kevät 2023', 11, 0, 0, 0, 0, 3, 6, 0], - ['Syksy 2022', 15, 0, 0, 0, 0, 3, 14, 0], - ['Kevät 2022', 29, 0, 0, 0, 0, 2, 7, 0], - ['Syksy 2021', 12, 0, 0, 0, 0, 0, 5, 0], - ['Kevät 2021', 3, 0, 0, 0, 0, 0, 3, 0], - ['Syksy 2020', 18, 0, 0, 1, 0, 2, 14, 1], - ['Kevät 2020', 3, 0, 0, 0, 1, 0, 2, 0], - ['Syksy 2019', 25, 0, 1, 4, 0, 5, 15, 0], - ['Kevät 2019', 7, 0, 0, 0, 1, 1, 5, 0], - ['Syksy 2018', 22, 2, 2, 1, 1, 2, 14, 0], - ['Kevät 2018', 18, 4, 0, 2, 0, 3, 9, 0], - ['Syksy 2017', 8, 0, 0, 0, 2, 2, 4, 0], - ['Kevät 2017', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 2016', 1, 0, 0, 0, 0, 1, 0, 0], - ] - toggleShowGrades() - toggleSeparateBySemesters() - checkTableContents(tableContents) - }) - }) - }) - - describe('Combine substitutions on', () => { - beforeEach(() => { - cy.url().should('include', '/coursestatistics') - cy.contains('Search for courses') - searchByCourseCode('TKT10002') - cy.cs(`course-TKT10002`).click() - cy.contains('Search for courses').should('not.exist') - cy.contains('TKT10002') // Ohjelmoinnin perusteet - cy.contains('AYTKT10002') // Avoin yo: Ohjelmoinnin perusteet - cy.contains('BSCS1001') // Introduction to Programming - cy.contains('581325') // Ohjelmoinnin perusteet - cy.contains('A581325') // Avoin yo: Ohjelmoinnin perusteet - }) - - it('Time range', () => { - cy.cs('FromYearSelector').click() - cy.cs('FromYearSelectorOption1999-2000').should('have.class', 'Mui-selected') - cy.get('[data-cy^="FromYearSelectorOption"]').should('have.length', 25) - clickAway() - - cy.cs('ToYearSelector').click() - cy.cs('ToYearSelectorOption2023-2024').should('have.class', 'Mui-selected') - cy.get('[data-cy^="ToYearSelectorOption"]').should('have.length', 25) - clickAway() - - cy.contains('Show population').should('be.enabled') - }) - - // TODO: Writing these as backend api tests - describe.skip('Students tab', () => { - it('Show grades off, Separate by semesters off', () => { - const tableContents = [ - // [Time, Total students, Passed, Failed, Enrolled no grade, Pass rate, Fail rate] - ['Total', 277, 237, 8, 32, '85.56 %', '14.44 %'], - ['2023-2024', 8, 2, 0, 6, '25.00 %', '75.00 %'], - ['2022-2023', 34, 27, 0, 7, '79.41 %', '20.59 %'], - ['2021-2022', 45, 26, 0, 19, '57.78 %', '42.22 %'], - ['2020-2021', 31, 31, 0, null, '100.00 %', '0.00 %'], - ['2019-2020', 56, 56, 0, null, '100.00 %', '0.00 %'], - ['2018-2019', 41, 39, 2, null, '95.12 %', '4.88 %'], - ['2017-2018', 32, 28, 4, null, '87.50 %', '12.50 %'], - ['2016-2017', 6, 5, 1, null, '83.33 %', '16.67 %'], - ['2015-2016', 4, 4, 0, null, '100.00 %', '0.00 %'], - ['2014-2015', 5, 5, 0, null, '100.00 %', '0.00 %'], - ['2013-2014', 2, 2, 0, null, '100.00 %', '0.00 %'], - ['2012-2013', 4, 4, 0, null, '100.00 %', '0.00 %'], - ['2011-2012', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['2010-2011', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['2009-2010', 0, 0, 0, null, '–', '–'], - ['2008-2009', 1, 0, 1, null, '0.00 %', '100.00 %'], - ['2007-2008', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['2006-2007', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['2005-2006', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['2004-2005', 0, 0, 0, null, '–', '–'], - ['2003-2004', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['2002-2003', 0, 0, 0, null, '–', '–'], - ['2001-2002', 0, 0, 0, null, '–', '–'], - ['2000-2001', 0, 0, 0, null, '–', '–'], - ['1999-2000', 2, 2, 0, null, '100.00 %', '0.00 %'], - ] - checkTableContents(tableContents) - }) - - it('Show grades off, Separate by semesters on', () => { - const tableContents = [ - // [Time, Total students, Passed, Failed, Enrolled no grade, Pass rate, Fail rate] - ['Total', 282, 237, 9, 36, '84.04 %', '15.96 %'], - ['Syksy 2023', 8, 2, 0, 6, '25.00 %', '75.00 %'], - ['Kevät 2023', 12, 10, 0, 2, '83.33 %', '16.67 %'], - ['Syksy 2022', 22, 17, 0, 5, '77.27 %', '22.73 %'], - ['Kevät 2022', 28, 11, 0, 17, '39.29 %', '60.71 %'], - ['Syksy 2021', 21, 15, 0, 6, '71.43 %', '28.57 %'], - ['Kevät 2021', 7, 7, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2020', 24, 24, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2020', 24, 24, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2019', 32, 32, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2019', 15, 14, 1, null, '93.33 %', '6.67 %'], - ['Syksy 2018', 27, 25, 2, null, '92.59 %', '7.41 %'], - ['Kevät 2018', 23, 19, 4, null, '82.61 %', '17.39 %'], - ['Syksy 2017', 9, 9, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2017', 4, 3, 1, null, '75.00 %', '25.00 %'], - ['Syksy 2016', 2, 2, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2016', 3, 3, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2015', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2015', 3, 3, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2014', 2, 2, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2014', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2013', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2013', 0, 0, 0, 0, '–', '–'], - ['Syksy 2012', 4, 4, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2012', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2011', 0, 0, 0, 0, '–', '–'], - ['Kevät 2011', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2010', 0, 0, 0, 0, '–', '–'], - ['Kevät 2010', 0, 0, 0, 0, '–', '–'], - ['Syksy 2009', 0, 0, 0, 0, '–', '–'], - ['Kevät 2009', 0, 0, 0, 0, '–', '–'], - ['Syksy 2008', 1, 0, 1, null, '0.00 %', '100.00 %'], - ['Kevät 2008', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2007', 0, 0, 0, 0, '–', '–'], - ['Kevät 2007', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2006', 0, 0, 0, 0, '–', '–'], - ['Kevät 2006', 0, 0, 0, 0, '–', '–'], - ['Syksy 2005', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2005', 0, 0, 0, 0, '–', '–'], - ['Syksy 2004', 0, 0, 0, 0, '–', '–'], - ['Kevät 2004', 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2003', 0, 0, 0, 0, '–', '–'], - ['Kevät 2003', 0, 0, 0, 0, '–', '–'], - ['Syksy 2002', 0, 0, 0, 0, '–', '–'], - ['Kevät 2002', 0, 0, 0, 0, '–', '–'], - ['Syksy 2001', 0, 0, 0, 0, '–', '–'], - ['Kevät 2001', 0, 0, 0, 0, '–', '–'], - ['Syksy 2000', 0, 0, 0, 0, '–', '–'], - ['Kevät 2000', 0, 0, 0, 0, '–', '–'], - ['Syksy 1999', 2, 2, 0, null, '100.00 %', '0.00 %'], - ] - toggleSeparateBySemesters() - checkTableContents(tableContents) - }) - - it('Show grades on, Separate by semesters off', () => { - const tableContents = [ - // [Time, Total students, Failed, 1, 2, 3, 4, 5, Other passed, Enrolled no grade, Pass rate, Fail rate] - ['Total', 277, 8, 4, 14, 9, 37, 168, 5, 32, '85.56 %', '14.44 %'], - ['2023-2024', 8, 0, 0, 0, 0, 0, 2, 0, 6, '25.00 %', '75.00 %'], - ['2022-2023', 34, 0, 0, 0, 0, 6, 21, 0, 7, '79.41 %', '20.59 %'], - ['2021-2022', 45, 0, 0, 1, 0, 2, 23, 0, 19, '57.78 %', '42.22 %'], - ['2020-2021', 31, 0, 0, 1, 1, 2, 26, 1, null, '100.00 %', '0.00 %'], - ['2019-2020', 56, 0, 1, 5, 3, 9, 38, 0, null, '100.00 %', '0.00 %'], - ['2018-2019', 41, 2, 3, 2, 2, 6, 26, 0, null, '95.12 %', '4.88 %'], - ['2017-2018', 32, 4, 0, 3, 2, 6, 17, 0, null, '87.50 %', '12.50 %'], - ['2016-2017', 6, 1, 0, 0, 1, 1, 3, 0, null, '83.33 %', '16.67 %'], - ['2015-2016', 4, 0, 0, 1, 0, 0, 2, 1, null, '100.00 %', '0.00 %'], - ['2014-2015', 5, 0, 0, 1, 0, 0, 1, 3, null, '100.00 %', '0.00 %'], - ['2013-2014', 2, 0, 0, 0, 0, 0, 2, 0, null, '100.00 %', '0.00 %'], - ['2012-2013', 4, 0, 0, 0, 0, 3, 1, 0, null, '100.00 %', '0.00 %'], - ['2011-2012', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['2010-2011', 1, 0, 0, 0, 0, 1, 0, 0, null, '100.00 %', '0.00 %'], - ['2009-2010', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['2008-2009', 1, 1, 0, 0, 0, 0, 0, 0, null, '0.00 %', '100.00 %'], - ['2007-2008', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['2006-2007', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['2005-2006', 1, 0, 0, 0, 0, 1, 0, 0, null, '100.00 %', '0.00 %'], - ['2004-2005', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['2003-2004', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['2002-2003', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['2001-2002', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['2000-2001', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['1999-2000', 2, 0, 0, 0, 0, 0, 2, 0, null, '100.00 %', '0.00 %'], - ] - toggleShowGrades() - checkTableContents(tableContents) - }) - - it('Show grades on, Separate by semesters on', () => { - const tableContents = [ - // [Time, Total students, Failed, 1, 2, 3, 4, 5, Other passed, Enrolled no grade, Pass rate, Fail rate] - ['Total', 282, 9, 4, 14, 9, 37, 168, 5, 36, '84.04 %', '15.96 %'], - ['Syksy 2023', 8, 0, 0, 0, 0, 0, 2, 0, 6, '25.00 %', '75.00 %'], - ['Kevät 2023', 12, 0, 0, 0, 0, 3, 7, 0, 2, '83.33 %', '16.67 %'], - ['Syksy 2022', 22, 0, 0, 0, 0, 3, 14, 0, 5, '77.27 %', '22.73 %'], - ['Kevät 2022', 28, 0, 0, 0, 0, 2, 9, 0, 17, '39.29 %', '60.71 %'], - ['Syksy 2021', 21, 0, 0, 1, 0, 0, 14, 0, 6, '71.43 %', '28.57 %'], - ['Kevät 2021', 7, 0, 0, 0, 0, 0, 7, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2020', 24, 0, 0, 1, 1, 2, 19, 1, null, '100.00 %', '0.00 %'], - ['Kevät 2020', 24, 0, 0, 1, 2, 4, 17, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2019', 32, 0, 1, 4, 1, 5, 21, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2019', 15, 1, 1, 1, 1, 2, 9, 0, null, '93.33 %', '6.67 %'], - ['Syksy 2018', 27, 2, 2, 1, 1, 4, 17, 0, null, '92.59 %', '7.41 %'], - ['Kevät 2018', 23, 4, 0, 3, 0, 4, 12, 0, null, '82.61 %', '17.39 %'], - ['Syksy 2017', 9, 0, 0, 0, 2, 2, 5, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2017', 4, 1, 0, 0, 1, 0, 2, 0, null, '75.00 %', '25.00 %'], - ['Syksy 2016', 2, 0, 0, 0, 0, 1, 1, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2016', 3, 0, 0, 1, 0, 0, 2, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2015', 1, 0, 0, 0, 0, 0, 0, 1, null, '100.00 %', '0.00 %'], - ['Kevät 2015', 3, 0, 0, 0, 0, 0, 0, 3, null, '100.00 %', '0.00 %'], - ['Syksy 2014', 2, 0, 0, 1, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2014', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2013', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2013', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Syksy 2012', 4, 0, 0, 0, 0, 3, 1, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2012', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2011', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2011', 1, 0, 0, 0, 0, 1, 0, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2010', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2010', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Syksy 2009', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2009', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Syksy 2008', 1, 1, 0, 0, 0, 0, 0, 0, null, '0.00 %', '100.00 %'], - ['Kevät 2008', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2007', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2007', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2006', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2006', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Syksy 2005', 1, 0, 0, 0, 0, 1, 0, 0, null, '100.00 %', '0.00 %'], - ['Kevät 2005', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Syksy 2004', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2004', 1, 0, 0, 0, 0, 0, 1, 0, null, '100.00 %', '0.00 %'], - ['Syksy 2003', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2003', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Syksy 2002', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2002', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Syksy 2001', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2001', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Syksy 2000', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Kevät 2000', 0, 0, 0, 0, 0, 0, 0, 0, null, '–', '–'], - ['Syksy 1999', 2, 0, 0, 0, 0, 0, 2, 0, null, '100.00 %', '0.00 %'], - ] - toggleShowGrades() - toggleSeparateBySemesters() - checkTableContents(tableContents) - }) - }) - - // TODO: Writing these as backend api tests - describe.skip('Attempts tab', () => { - beforeEach(() => { - openAttemptsTab() - }) - - it('Show grades off, Separate by semesters off', () => { - const tableContents = [ - // [Time, Total attempts, Passed, Failed, Pass rate, Enrollments] - ['Total', 270, 237, 9, '96.34 %', 79], - ['2023-2024', 6, 2, 0, '33.33 %', 6], - ['2022-2023', 28, 27, 0, '96.43 %', 28], - ['2021-2022', 45, 26, 0, '57.78 %', 45], - ['2020-2021', 31, 31, 0, '100.00 %', null], - ['2019-2020', 56, 56, 0, '100.00 %', null], - ['2018-2019', 42, 39, 3, '92.86 %', null], - ['2017-2018', 32, 28, 4, '87.50 %', null], - ['2016-2017', 6, 5, 1, '83.33 %', null], - ['2015-2016', 4, 4, 0, '100.00 %', null], - ['2014-2015', 5, 5, 0, '100.00 %', null], - ['2013-2014', 2, 2, 0, '100.00 %', null], - ['2012-2013', 4, 4, 0, '100.00 %', null], - ['2011-2012', 1, 1, 0, '100.00 %', null], - ['2010-2011', 1, 1, 0, '100.00 %', null], - ['2009-2010', 0, 0, 0, '–', null], - ['2008-2009', 1, 0, 1, '0.00 %', null], - ['2007-2008', 1, 1, 0, '100.00 %', null], - ['2006-2007', 1, 1, 0, '100.00 %', null], - ['2005-2006', 1, 1, 0, '100.00 %', null], - ['2004-2005', 0, 0, 0, '–', null], - ['2003-2004', 1, 1, 0, '100.00 %', null], - ['2002-2003', 0, 0, 0, '–', null], - ['2001-2002', 0, 0, 0, '–', null], - ['2000-2001', 0, 0, 0, '–', null], - ['1999-2000', 2, 2, 0, '100.00 %', null], - ] - checkTableContents(tableContents) - }) - - it('Show grades off, Separate by semesters on', () => { - const tableContents = [ - // [Time, Total attempts, Passed, Failed, Pass rate, Enrollments] - ['Total', 270, 237, 9, '96.34 %', 79], - ['Syksy 2023', 6, 2, 0, '33.33 %', 6], - ['Kevät 2023', 13, 10, 0, '76.92 %', 13], - ['Syksy 2022', 15, 17, 0, '100.00 %', 15], - ['Kevät 2022', 30, 11, 0, '36.67 %', 30], - ['Syksy 2021', 15, 15, 0, '100.00 %', 15], - ['Kevät 2021', 7, 7, 0, '100.00 %', null], - ['Syksy 2020', 24, 24, 0, '100.00 %', null], - ['Kevät 2020', 24, 24, 0, '100.00 %', null], - ['Syksy 2019', 32, 32, 0, '100.00 %', null], - ['Kevät 2019', 15, 14, 1, '93.33 %', null], - ['Syksy 2018', 27, 25, 2, '92.59 %', null], - ['Kevät 2018', 23, 19, 4, '82.61 %', null], - ['Syksy 2017', 9, 9, 0, '100.00 %', null], - ['Kevät 2017', 4, 3, 1, '75.00 %', null], - ['Syksy 2016', 2, 2, 0, '100.00 %', null], - ['Kevät 2016', 3, 3, 0, '100.00 %', null], - ['Syksy 2015', 1, 1, 0, '100.00 %', null], - ['Kevät 2015', 3, 3, 0, '100.00 %', null], - ['Syksy 2014', 2, 2, 0, '100.00 %', null], - ['Kevät 2014', 1, 1, 0, '100.00 %', null], - ['Syksy 2013', 1, 1, 0, '100.00 %', null], - ['Kevät 2013', 0, 0, 0, '–', null], - ['Syksy 2012', 4, 4, 0, '100.00 %', null], - ['Kevät 2012', 1, 1, 0, '100.00 %', null], - ['Syksy 2011', 0, 0, 0, '–', null], - ['Kevät 2011', 1, 1, 0, '100.00 %', null], - ['Syksy 2010', 0, 0, 0, '–', null], - ['Kevät 2010', 0, 0, 0, '–', null], - ['Syksy 2009', 0, 0, 0, '–', null], - ['Kevät 2009', 0, 0, 0, '–', null], - ['Syksy 2008', 1, 0, 1, '0.00 %', null], - ['Kevät 2008', 1, 1, 0, '100.00 %', null], - ['Syksy 2007', 0, 0, 0, '–', null], - ['Kevät 2007', 1, 1, 0, '100.00 %', null], - ['Syksy 2006', 0, 0, 0, '–', null], - ['Kevät 2006', 0, 0, 0, '–', null], - ['Syksy 2005', 1, 1, 0, '100.00 %', null], - ['Kevät 2005', 0, 0, 0, '–', null], - ['Syksy 2004', 0, 0, 0, '–', null], - ['Kevät 2004', 1, 1, 0, '100.00 %', null], - ['Syksy 2003', 0, 0, 0, '–', null], - ['Kevät 2003', 0, 0, 0, '–', null], - ['Syksy 2002', 0, 0, 0, '–', null], - ['Kevät 2002', 0, 0, 0, '–', null], - ['Syksy 2001', 0, 0, 0, '–', null], - ['Kevät 2001', 0, 0, 0, '–', null], - ['Syksy 2000', 0, 0, 0, '–', null], - ['Kevät 2000', 0, 0, 0, '–', null], - ['Syksy 1999', 2, 2, 0, '100.00 %', null], - ] - toggleSeparateBySemesters() - checkTableContents(tableContents) - }) - - it('Show grades on, Separate by semesters off', () => { - const tableContents = [ - // [Time, Total attempts, 0, 1, 2, 3, 4, 5, Other passed] - ['Total', 270, 9, 4, 14, 9, 37, 168, 5], - ['2023-2024', 6, 0, 0, 0, 0, 0, 2, 0], - ['2022-2023', 28, 0, 0, 0, 0, 6, 21, 0], - ['2021-2022', 45, 0, 0, 1, 0, 2, 23, 0], - ['2020-2021', 31, 0, 0, 1, 1, 2, 26, 1], - ['2019-2020', 56, 0, 1, 5, 3, 9, 38, 0], - ['2018-2019', 42, 3, 3, 2, 2, 6, 26, 0], - ['2017-2018', 32, 4, 0, 3, 2, 6, 17, 0], - ['2016-2017', 6, 1, 0, 0, 1, 1, 3, 0], - ['2015-2016', 4, 0, 0, 1, 0, 0, 2, 1], - ['2014-2015', 5, 0, 0, 1, 0, 0, 1, 3], - ['2013-2014', 2, 0, 0, 0, 0, 0, 2, 0], - ['2012-2013', 4, 0, 0, 0, 0, 3, 1, 0], - ['2011-2012', 1, 0, 0, 0, 0, 0, 1, 0], - ['2010-2011', 1, 0, 0, 0, 0, 1, 0, 0], - ['2009-2010', 0, 0, 0, 0, 0, 0, 0, 0], - ['2008-2009', 1, 1, 0, 0, 0, 0, 0, 0], - ['2007-2008', 1, 0, 0, 0, 0, 0, 1, 0], - ['2006-2007', 1, 0, 0, 0, 0, 0, 1, 0], - ['2005-2006', 1, 0, 0, 0, 0, 1, 0, 0], - ['2004-2005', 0, 0, 0, 0, 0, 0, 0, 0], - ['2003-2004', 1, 0, 0, 0, 0, 0, 1, 0], - ['2002-2003', 0, 0, 0, 0, 0, 0, 0, 0], - ['2001-2002', 0, 0, 0, 0, 0, 0, 0, 0], - ['2000-2001', 0, 0, 0, 0, 0, 0, 0, 0], - ['1999-2000', 2, 0, 0, 0, 0, 0, 2, 0], - ] - toggleShowGrades() - checkTableContents(tableContents) - }) - - it('Show grades on, Separate by semesters on', () => { - const tableContents = [ - // [Time, Total attempts, 0, 1, 2, 3, 4, 5, Other passed] - ['Total', 270, 9, 4, 14, 9, 37, 168, 5], - ['Syksy 2023', 6, 0, 0, 0, 0, 0, 2, 0], - ['Kevät 2023', 13, 0, 0, 0, 0, 3, 7, 0], - ['Syksy 2022', 15, 0, 0, 0, 0, 3, 14, 0], - ['Kevät 2022', 30, 0, 0, 0, 0, 2, 9, 0], - ['Syksy 2021', 15, 0, 0, 1, 0, 0, 14, 0], - ['Kevät 2021', 7, 0, 0, 0, 0, 0, 7, 0], - ['Syksy 2020', 24, 0, 0, 1, 1, 2, 19, 1], - ['Kevät 2020', 24, 0, 0, 1, 2, 4, 17, 0], - ['Syksy 2019', 32, 0, 1, 4, 1, 5, 21, 0], - ['Kevät 2019', 15, 1, 1, 1, 1, 2, 9, 0], - ['Syksy 2018', 27, 2, 2, 1, 1, 4, 17, 0], - ['Kevät 2018', 23, 4, 0, 3, 0, 4, 12, 0], - ['Syksy 2017', 9, 0, 0, 0, 2, 2, 5, 0], - ['Kevät 2017', 4, 1, 0, 0, 1, 0, 2, 0], - ['Syksy 2016', 2, 0, 0, 0, 0, 1, 1, 0], - ['Kevät 2016', 3, 0, 0, 1, 0, 0, 2, 0], - ['Syksy 2015', 1, 0, 0, 0, 0, 0, 0, 1], - ['Kevät 2015', 3, 0, 0, 0, 0, 0, 0, 3], - ['Syksy 2014', 2, 0, 0, 1, 0, 0, 1, 0], - ['Kevät 2014', 1, 0, 0, 0, 0, 0, 1, 0], - ['Syksy 2013', 1, 0, 0, 0, 0, 0, 1, 0], - ['Kevät 2013', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 2012', 4, 0, 0, 0, 0, 3, 1, 0], - ['Kevät 2012', 1, 0, 0, 0, 0, 0, 1, 0], - ['Syksy 2011', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2011', 1, 0, 0, 0, 0, 1, 0, 0], - ['Syksy 2010', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2010', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 2009', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2009', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 2008', 1, 1, 0, 0, 0, 0, 0, 0], - ['Kevät 2008', 1, 0, 0, 0, 0, 0, 1, 0], - ['Syksy 2007', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2007', 1, 0, 0, 0, 0, 0, 1, 0], - ['Syksy 2006', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2006', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 2005', 1, 0, 0, 0, 0, 1, 0, 0], - ['Kevät 2005', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 2004', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2004', 1, 0, 0, 0, 0, 0, 1, 0], - ['Syksy 2003', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2003', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 2002', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2002', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 2001', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2001', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 2000', 0, 0, 0, 0, 0, 0, 0, 0], - ['Kevät 2000', 0, 0, 0, 0, 0, 0, 0, 0], - ['Syksy 1999', 2, 0, 0, 0, 0, 0, 2, 0], - ] - toggleShowGrades() - toggleSeparateBySemesters() - checkTableContents(tableContents) - }) - }) - - it('After changing time range shows correct options', () => { - cy.cs('FromYearSelector').click() - cy.cs('FromYearSelectorOption2016-2017').click() - cy.cs('FromYearSelectorOption2016-2017').should('have.class', 'Mui-selected') - clickAway() - - cy.cs('ToYearSelector').click() - cy.cs('ToYearSelectorOption2019-2020').click() - cy.cs('ToYearSelectorOption2019-2020').should('have.class', 'Mui-selected') - clickAway() - - cy.cs('FromYearSelector').click() - cy.get('[data-cy^="FromYearSelectorOption"]').should('have.length', 21) - clickAway() - - cy.cs('ToYearSelector').click() - cy.get('[data-cy^="ToYearSelectorOption"]').should('have.length', 8) - clickAway() - - cy.contains('Show population').should('be.enabled') - }) - }) - - it('If no data available, provider organization(s) select is disabled', () => { - searchByCourseCode('TKT20014') - cy.contains('TKT20014').click() - - cy.contains('TKT20014') // Kypsyysnäyte LuK - cy.contains('50037') // Ruotsinkielinen kypsyysnäyte LuK - cy.contains('50036') // Suomenkielinen kypsyysnäyte LuK - - cy.cs('ProviderOrganizationSelect').click() - - cy.cs('ProviderOrganizationSelectOptionBoth').should('have.class', 'Mui-selected') - cy.cs('ProviderOrganizationSelectOptionBoth').should('not.have.class', 'Mui-disabled') - cy.cs('ProviderOrganizationSelectOptionBoth').should('have.text', 'University + Open university') - - cy.cs('ProviderOrganizationSelectOptionRegular').should('not.have.class', 'Mui-selected') - cy.cs('ProviderOrganizationSelectOptionRegular').should('not.have.class', 'Mui-disabled') - cy.cs('ProviderOrganizationSelectOptionRegular').should('have.text', 'University') - cy.cs('ProviderOrganizationSelectOptionRegular').should('not.have.text', 'University (not available)') - - cy.cs('ProviderOrganizationSelectOptionOpen').should('not.have.class', 'Mui-selected') - cy.cs('ProviderOrganizationSelectOptionOpen').should('have.class', 'Mui-disabled') - cy.cs('ProviderOrganizationSelectOptionOpen').should('have.text', 'Open university (not available)') - cy.cs('ProviderOrganizationSelectOptionOpen').should('not.have.text', 'University') - }) - - it('Has right to see all the students, because course rovider is TKT', () => { - cy.visit('coursestatistics?courseCodes=%5B%22TKT10004%22%5D&separate=false') - cy.cs('course-population-for-2021-2022').click() - // cy.contains('Students (29)').click() - }) - }) -}) - -// TODO: Writing these as backend api tests -describe.skip('Only course statistics', () => { - beforeEach(() => { - cy.init('/coursestatistics', 'onlycoursestatistics') - cy.url().should('include', '/coursestatistics') - }) - - it('Some features of Course Statistics are hidden for courseStatistics-users without other rights', () => { - const coursecode = 'TKT10002' - getCourseSearchHooksForSingleYear(coursecode) - - searchByCourseCode(coursecode) - cy.wait('@courses').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.contains('tr', coursecode).click() - - cy.wait('@yearlystats').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.url().should('contain', `courseCodes=%5B%22${coursecode}%22%5D`) - - cy.contains('Filter statistics by degree programmes').should('not.exist') - cy.contains('Show population').should('not.exist') - cy.contains('Faculty statistics').should('be.disabled') - - openAttemptsTab() - const emptyYear = year => [year, 'NA', 'NA', 'NA', 'NA', 'NA'] - - const attemptsTableContents = [ - // [Time, Total attempts, Passed, Failed, Pass rate, Enrollments] - ['Total *', 240, 212, 8, '96.36 %', 73], - emptyYear('2023-2024'), - ['2022-2023', 28, 27, 0, '96.43 %', 28], - ['2021-2022', 45, 26, 0, '57.78 %', 45], - ['2020-2021', 31, 31, 0, '100.00 %'], - ['2019-2020', 56, 56, 0, '100.00 %'], - ['2018-2019', 42, 39, 3, '92.86 %'], - ['2017-2018', 32, 28, 4, '87.50 %'], - ['2016-2017', 6, 5, 1, '83.33 %'], - emptyYear('2015-2016'), - emptyYear('2014-2015'), - emptyYear('2013-2014'), - emptyYear('2012-2013'), - emptyYear('2011-2012'), - emptyYear('2010-2011'), - emptyYear('2009-2010'), - emptyYear('2008-2009'), - emptyYear('2007-2008'), - emptyYear('2006-2007'), - emptyYear('2005-2006'), - emptyYear('2004-2005'), - emptyYear('2003-2004'), - emptyYear('2002-2003'), - emptyYear('2001-2002'), - emptyYear('2000-2001'), - emptyYear('1999-2000'), - ] - - openAttemptsTab() - checkTableContents(attemptsTableContents) - }) -}) diff --git a/cypress/e2e/Custom_population.js b/cypress/e2e/Custom_population.js deleted file mode 100644 index 54715d4d2..000000000 --- a/cypress/e2e/Custom_population.js +++ /dev/null @@ -1,192 +0,0 @@ -/// - -const fillName = () => { - const name = `TEST-${new Date().getTime()}` - cy.contains('Insert a name for this custom population if you wish to save it') - cy.cs('custom-population-name-input').type(name) - return name -} - -const save = () => { - cy.get('button').contains('Save').click() -} - -const selectSavedPopulation = name => { - cy.cs('history-search').type(`${name}{enter}`) -} - -const deleteAllSearches = () => { - cy.cs('history-search').click() - cy.get('.MuiAutocomplete-popper > .MuiPaper-root') - .find('li[role=option]') - .then($lis => { - const labels = [...$lis].map(li => li.textContent?.trim() || '') - - labels.forEach((label, index) => { - if (index !== 0) cy.cs('history-search').click() - cy.contains('.MuiAutocomplete-popper li[role=option]', label).click() - cy.contains('button', 'Delete').click() - }) - }) -} - -const fillForm = (content, separator) => { - cy.cs('student-number-input').type(content.join(separator)) -} - -const search = () => { - cy.cs('search-button').click() -} - -const searchFor = (studentnumbers, separator) => { - fillForm(studentnumbers, separator) - search() -} - -const hasLanded = () => { - cy.contains('Credit accumulation') - cy.contains('Programme distribution') - cy.contains('Courses of population') - cy.contains('Students') -} - -const containsAmountOfStudents = (amount = 0) => { - cy.contains(`Credit accumulation (for ${amount} students)`) -} - -const containsSpecificStudents = (studentnumbers = []) => { - cy.contains(`Students (${studentnumbers.length})`) - .parent() - .then($parentDiv => { - if (!$parentDiv.hasClass('active')) cy.contains(`Students (${studentnumbers.length})`).click() - }) - - studentnumbers.forEach(s => cy.contains(s)) -} - -const checkRightsNotification = studentNumbers => { - cy.cs('rights-notification').within(() => { - cy.contains( - 'The following students information could not be displayed. This could be either because they do not exist, or you do not have the right to view their information.' - ) - cy.get('ul').within(() => { - studentNumbers.forEach(number => cy.get('li').contains(number)) - }) - }) -} - -describe('Custom population tests', () => { - const nonExistentStudentNumbers = ['123', 'X', '-'] - beforeEach(() => { - cy.init('/custompopulation') - cy.url().should('include', '/custompopulation') - cy.contains('Custom population') - }) - - after(() => { - cy.visit('/custompopulation') - cy.url().should('include', '/custompopulation') - cy.contains('Custom population') - deleteAllSearches() - }) - - describe('Custom population searching', () => { - it('Finds a proper population', () => { - cy.fixture('customPopulations').then(({ studentNumbersForCSStudentsSet1: students }) => { - searchFor(students, '\n') - hasLanded() - containsAmountOfStudents(students.length) - containsSpecificStudents(students) - }) - }) - - it("Doesn't return non-existing students", () => { - cy.fixture('customPopulations').then(({ studentNumbersForCSStudentsSet1: students }) => { - searchFor([...students, ...nonExistentStudentNumbers], ' ') - hasLanded() - containsAmountOfStudents(students.length) - containsSpecificStudents(students) - checkRightsNotification(nonExistentStudentNumbers) - }) - }) - - it("Doesn't find empty custom population", () => { - searchFor(nonExistentStudentNumbers, ',') - checkRightsNotification(nonExistentStudentNumbers) - cy.contains('Credit accumulation').should('not.exist') - cy.contains('Programme distribution').should('not.exist') - cy.contains('Courses of population').should('not.exist') - cy.get('button').contains('Back to search form') - }) - - it("Doesn't return students user has no right to", () => { - // These students exist in the database, but the user doesn't have the right to view them - const studentsForEduBachStudents = ['014990067', '013069465', '014853890'] - // Two semicolons on purpose, the page should be able to handle it - searchFor(studentsForEduBachStudents, ';;') - checkRightsNotification(studentsForEduBachStudents) - cy.contains('Credit accumulation').should('not.exist') - cy.contains('Programme distribution').should('not.exist') - cy.contains('Courses of population').should('not.exist') - cy.get('button').contains('Back to search form') - }) - }) - - describe('Custom population search saving', () => { - it('Saves a custom population search', { retries: 2 }, () => { - cy.fixture('customPopulations').then(({ studentNumbersForCSStudentsSet1: students }) => { - cy.contains( - 'Insert student numbers to use for the population. Each student number needs to be separated with a comma, a semicolon, a space, or a line break.' - ) - const name = fillName() - // A comma and a newline on purpose, the page should be able to handle it - fillForm(students, ',\n') - save() - - // Round 1 - selectSavedPopulation(name) - search() - cy.contains(`Custom population: ${name}`) - containsAmountOfStudents(students.length) - containsSpecificStudents(students) - - // Round 2 - cy.visit('/custompopulation') - cy.contains('Custom population') - selectSavedPopulation(name) - search() - cy.contains(`Custom population: ${name}`) - containsAmountOfStudents(students.length) - containsSpecificStudents(students) - }) - }) - - it('Updates a custom population search', () => { - cy.fixture('customPopulations').then( - ({ studentNumbersForCSStudentsSet1: students1, studentNumbersForCSStudentsSet2: students2 }) => { - const name = fillName() - fillForm(students1, ' ') - save() - - selectSavedPopulation(name) - search() - cy.contains(`Custom population: ${name}`) - containsAmountOfStudents(students1.length) - containsSpecificStudents(students1) - cy.contains('Back to search form').click() - selectSavedPopulation(name) - fillForm(['\n', ...students2], ', ') - save() - - cy.visit('/custompopulation') - cy.contains('Custom population') - selectSavedPopulation(name) - search() - cy.contains(`Custom population: ${name}`) - containsAmountOfStudents(students1.length + students2.length) - containsSpecificStudents([...students1, ...students2]) - } - ) - }) - }) -}) diff --git a/cypress/e2e/Degree_programme_overview.js b/cypress/e2e/Degree_programme_overview.js deleted file mode 100644 index d3cd564fc..000000000 --- a/cypress/e2e/Degree_programme_overview.js +++ /dev/null @@ -1,922 +0,0 @@ -/// - -const getEmptyYears = isAcademicYear => { - const today = new Date() - const latestYear = isAcademicYear && today.getMonth() < 7 ? today.getFullYear() - 1 : today.getFullYear() - - const years = [] - for (let year = latestYear; year >= 2024; year--) { - if (isAcademicYear) { - years.push(`${year} - ${year + 1}`) - } else { - years.push(year) - } - } - return years -} - -const tagName = `tag-${new Date().getTime()}` - -const selectYear = year => { - // ? Testing the MUI X DatePicker seems very difficult. It does not detect data-cy and the tests fail in CI/CD - cy.contains('Associated start year (optional)').click({ force: true }) - cy.get('[placeholder=YYYY]').type(year) -} - -const deleteTag = tagName => { - cy.cs(`delete-tag-${tagName}-button`).click() - cy.contains('Delete tag') - cy.contains('Are you sure you want to delete tag') - cy.cs('confirm-delete-tag-button').click() -} - -describe('Degree programme overview', () => { - describe('Degree programme selector', () => { - it('Degree programme search filter', () => { - cy.init('/study-programme', 'admin') - cy.contains('Tietojenkäsittelytieteen kandiohjelma').should('exist') - cy.contains('Matemaattisten tieteiden kandiohjelma').should('exist') - cy.cs('study-programme-filter').type('Tietojenkäsittelytieteen') - cy.contains('Tietojenkäsittelytieteen kandiohjelma').should('exist') - cy.contains('Matemaattisten tieteiden kandiohjelma').should('not.exist') - }) - }) - - describe('Basic information tab works for basic user', () => { - beforeEach(() => { - cy.init('/study-programme') - cy.contains('a', 'Matemaattisten tieteiden kandiohjelma').click({ force: true }) - cy.cs('year-toggle').click() // NOTE: Tests are written for calendar years - }) - - // If the backend breaks for one of the sections, the section header is not rendered and this will fail - it('Basic information tab loads', () => { - cy.cs('students-of-the-study-programme-section') - cy.cs('credits-produced-by-the-study-programme-section') - cy.cs('graduated-and-thesis-writers-of-the-programme-section') - cy.cs('programmes-before-or-after-section') - cy.cs('average-graduation-times-section') - }) - - it('Basic information contains correct students', () => { - const years = getEmptyYears() - const tableContents = [ - // [Year, Started studying, Accepted, Graduated, Cancelled, Transferred Away, Transferred to] - ...years.map(year => [year, 0, 0, 0, 0, 0]), - [2023, 8, 8, 26, 2, 0, 0], - [2022, 25, 26, 47, 0, 1, 3], - [2021, 29, 32, 48, 1, 0, 2], - [2020, 26, 27, 12, 0, 1, 3], - [2019, 28, 34, 1, 0, 0, 1], - [2018, 40, 45, 0, 0, 0, 1], - [2017, 41, 47, 0, 0, 0, 0], - ] - - cy.checkTableStats(tableContents, 'students-of-the-study-programme') - }) - - it('Basic information contains correct credits', () => { - const years = getEmptyYears() - const tableContents = [ - ...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - [2023, 1519, 1519, 0, 0, 0, 0, 0, 222, 0], - [2022, 3235, 3205, 0, 0, 30, 0, 0, 209, 0], - [2021, 5133, 5108, 0, 0, 25, 0, 0, 428, 25], - [2020, 5801, 5796, 0, 0, 5, 0, 0, 94, 0], - [2019, 5305, 5305, 0, 0, 0, 0, 0, 162, 0], - [2018, 3442, 3432, 0, 0, 10, 0, 0, 21, 0], - [2017, 1211, 1211, 0, 0, 0, 0, 0, 189, 0], - ] - - cy.checkTableStats(tableContents, 'credits-produced-by-the-study-programme') - }) - - it('Basic information contains correct thesis writers and graduates', () => { - const years = getEmptyYears() - const tableContents = [ - // [Year, Graduated, Wrote thesis] - ...years.map(year => [year, 0, 0]), - [2023, 26, 5], - [2022, 47, 13], - [2021, 48, 76], - [2020, 12, 23], - [2019, 1, 19], - [2018, 0, 0], - [2017, 0, 1], - ] - - cy.checkTableStats(tableContents, 'graduated-and-graduations-of-the-programme') - }) - - it('Special study rights can be excluded and basic data changes accordingly', () => { - cy.cs('study-right-toggle').click() - const years = getEmptyYears() - const studentTableContents = [ - // [Year, Started studying, Accepted, Graduated] - ...years.map(year => [year, 0, 0, 0]), - [2023, 8, 8, 24], - [2022, 25, 26, 43], - [2021, 29, 32, 47], - [2020, 26, 27, 11], - [2019, 28, 34, 1], - [2018, 40, 45, 0], - [2017, 41, 47, 0], - ] - - cy.checkTableStats(studentTableContents, 'students-of-the-study-programme') - - const graduatedTableContents = [ - // [Year, Graduated, Wrote thesis] - ...years.map(year => [year, 0, 0]), - [2023, 24, 5], - [2022, 43, 12], - [2021, 47, 69], - [2020, 11, 22], - [2019, 1, 18], - [2018, 0, 0], - [2017, 0, 1], - ] - - cy.checkTableStats(graduatedTableContents, 'graduated-and-graduations-of-the-programme') - }) - - it('Year can be changed to academic year, and data changes accordingly', () => { - cy.cs('year-toggle').click() - const isAcademicYear = true - const years = getEmptyYears(isAcademicYear) - const studentTableContents = [ - // [Year, Started studying, Accepted, Graduated, Cancelled, Transferred away, Transferred to] - ...years.map(year => [year, 0, 0, 0, 0, 0]), - ['2023 - 2024', 8, 8, 4, 1, 0, 0], - ['2022 - 2023', 25, 26, 35, 1, 0, 0], - ['2021 - 2022', 29, 32, 58, 1, 1, 5], - ['2020 - 2021', 26, 27, 30, 0, 0, 3], - ['2019 - 2020', 28, 34, 7, 0, 1, 1], - ['2018 - 2019', 40, 45, 0, 0, 0, 1], - ['2017 - 2018', 41, 47, 0, 0, 0, 0], - ] - cy.checkTableStats(studentTableContents, 'students-of-the-study-programme') - - const creditTableContents = [ - ...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - ['2023 - 2024', 160, 160, 0, 0, 0, 0, 0, 67, 0], - ['2022 - 2023', 2725, 2720, 0, 0, 5, 0, 0, 337, 0], - ['2021 - 2022', 4092, 4042, 0, 0, 50, 0, 0, 198, 0], - ['2020 - 2021', 5420, 5415, 0, 0, 5, 0, 0, 321, 25], - ['2019 - 2020', 6043, 6043, 0, 0, 0, 0, 0, 101, 0], - ['2018 - 2019', 4856, 4851, 0, 0, 5, 0, 0, 107, 0], - ['2017 - 2018', 2350, 2345, 0, 0, 5, 0, 0, 26, 0], - ] - - cy.checkTableStats(creditTableContents, 'credits-produced-by-the-study-programme') - cy.cs('year-toggle').click() - }) - - it('Basic information graphs render', () => { - cy.cs('students-of-the-study-programme-line-graph-section') - .should('contain', 'Started studying') - .should('contain', 'Accepted') - .should('contain', 'Graduated') - .should('contain', 'Transferred away') - .should('contain', 'Transferred to') - - cy.cs('credits-produced-by-the-study-programme-stacked-bar-chart-section') - .should('contain', 'Degree students') - .should('contain', 'Transferred') - .should('contain', 5796) - .should('contain', 428) - - cy.cs('graduated-and-thesis-writers-of-the-programme-bar-chart-section') - .should('contain', 'Graduated students') - .should('contain', 'Wrote thesis') - .should('contain', 47) - .should('contain', 76) - - cy.cs('graduation-mode-selector').within(() => { - cy.cs('select-median').click() - }) - cy.cs('unset-median-bar-chart').within(() => { - cy.contains('47 graduated').should('be.visible') - cy.contains('47 graduated').hover() - }) - - cy.get('.grad-vals').contains('47 students graduated in year 2022').should('be.visible') - - cy.contains('median study time: 6 semesters') - cy.contains('24 graduated on time') - cy.contains('12 graduated max year overtime') - cy.contains('11 graduated over year late') - - cy.cs('programmes-before-or-after-stacked-bar-chart-section') - .should('contain', 'Tietojenkäsittelytieteen maisteriohjelma') - .should('contain', 'Datatieteen maisteriohjelma') - .should('contain', 'Matematiikan ja tilastotieteen maisteriohjelma') - .should('contain', 32) - .should('contain', 21) - .should('contain', 17) - }) - }) - - describe('Graduation times of master programmes', () => { - it('are split into three graphs', () => { - cy.init('/study-programme') - cy.contains('a', 'Matematiikan ja tilastotieteen maisteriohjelma').click({ force: true }) - cy.cs('year-toggle').click() // Tests are written for calendar year - - cy.cs('unset-breakdown-bar-chart') - - cy.cs('graduation-mode-selector').within(() => { - cy.cs('select-average').click() - }) - cy.cs('unset-graduation-times-section') - .eq(1) - .within(() => { - cy.contains('Master study right') - cy.contains('2 graduated').should('be.visible') - cy.contains('2 graduated').hover() - }) - - cy.get('.grad-vals').contains('2 students graduated in year 2021').should('be.visible') - cy.contains('average study time: 4.5 semesters') - cy.contains('1 graduated on time') - cy.contains('1 graduated max year overtime') - cy.contains('0 graduated over year late') - - cy.cs('unset-graduation-times-section') - .eq(0) - .within(() => { - cy.contains('Bachelor + master study right') - cy.contains('11 graduated').should('be.visible') - cy.contains('11 graduated').hover() - }) - - cy.get('.grad-vals').contains('11 students graduated in year 2023').should('be.visible') - cy.contains('average study time: 11.18 semesters') - cy.contains('4 graduated on time') - cy.contains('6 graduated max year overtime') - cy.contains('1 graduated over year late') - }) - }) - - describe('Study tracks and class statistics tab works for basic user', () => { - beforeEach(() => { - cy.intercept( - 'GET', - 'api/studyprogrammes/KH50_001/studytrackstats?special_groups=SPECIAL_INCLUDED&combined_programme=' - ).as('stQuery') - cy.init('/study-programme') - cy.contains('a', 'Matemaattisten tieteiden kandiohjelma').click() - cy.cs('StudyTracksAndClassStatisticsTab').click() - }) - - describe('Info boxes', () => { - it('Study track overview section', () => { - cy.cs('study-track-overview-info-box-button').click() - cy.cs('study-track-overview-info-box-content').contains('Opiskelijat, joiden') - }) - - it('Progress of students section', () => { - cy.cs('progress-of-students-info-box-button').click() - cy.cs('progress-of-students-info-box-content').contains('Kuvaa koulutusohjelmassa') - }) - - // HACK: Do this properly - it('Average graduation times section', () => { - cy.wait(500) - cy.cs('average-graduation-times-info-box-button').click() - cy.cs('average-graduation-times-info-box-content').contains('Yksittäinen palkki') - }) - }) - - it('All sections are visible', () => { - cy.cs('study-track-selector-section') - cy.cs('study-track-overview-section') - cy.cs('progress-of-students-section') - cy.cs('average-graduation-times-section') - }) - - it('Students of the degree programme are shown correctly', () => { - const tableContents = [ - // [Year, All, Started studying, Present, Absent, Passive, Graduated, Has recent attainments, Men, Women, Other/Unknown, Finland, Other] - ['2023 - 2024', 8, 8, 0, 0, 8, 0, 0, 5, 3, 0, 8, 1], - ['2022 - 2023', 26, 25, 0, 0, 24, 2, 0, 19, 7, 0, 25, 1], - ['2021 - 2022', 37, 29, 0, 0, 33, 4, 0, 29, 8, 0, 35, 4], - ['2020 - 2021', 30, 26, 0, 0, 11, 19, 0, 15, 15, 0, 29, 3], - ['2019 - 2020', 35, 28, 0, 0, 8, 27, 0, 22, 13, 0, 35, 2], - ['2018 - 2019', 46, 40, 0, 0, 6, 40, 0, 26, 20, 0, 45, 1], - ['2017 - 2018', 47, 41, 0, 0, 5, 42, 0, 31, 16, 0, 47, 0], - ['Total', 229, 197, 0, 0, 95, 134, 0, 147, 82, 0, 224, 12], - ] - - cy.checkTableStats(tableContents, 'study-tracks-and-class-statistics') - }) - - it.skip('Years in the students table can be expanded and study track data will be shown', () => { - // TODO: Fix this test - cy.cs('study-tracks-and-class-statistics-data-table').within(() => { - cy.get('tbody tr.header-row') - .eq(3) - .within(() => { - cy.get('td i.angle.right.icon').click() - }) - - const dataForStudyTracks = [ - ['Ekonometria, MAT-EKO', 2, 2, 0, 0, 0, 2, 1, 1, 0, 2, 0], - ['Matematiikka, MAT-MAT', 13, 10, 0, 0, 1, 12, 7, 6, 0, 12, 3], - ['Tietojenkäsittelyteoria, MAT-TIE', 2, 1, 0, 0, 1, 1, 2, 0, 0, 2, 0], - ['Tilastotiede, MAT-TIL', 4, 4, 0, 0, 0, 4, 1, 3, 0, 4, 0], - ] - - dataForStudyTracks.forEach((data, index) => { - cy.get('tbody tr.regular-row') - .eq(index) - .within(() => { - cy.get('td').each((cell, i) => { - cy.wrap(cell).contains(data[i]) - }) - }) - }) - - cy.get('tbody tr.header-row') - .eq(3) - .within(() => { - cy.get('td i.angle.down.icon').click() - }) - - cy.get('tbody tr.regular-row').should('not.exist') - }) - }) - - describe('Population link button works for', () => { - it('a single year', () => { - cy.cs('2023-population-link-button').first().click() - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Class of 2023 - 2024, 8 students') - }) - - it('total', () => { - cy.cs('total-population-link-button').click() - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Class of 2017 - 2026, 227 students') - }) - - it('Links to class statistics page with study track info included work', () => { - cy.cs('show-study-tracks-button').first().click() - cy.contains('td', 'Matematiikka (MAT-MAT)').within(() => { - cy.get('a').click() - }) - - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Studytrack MAT-MAT') - cy.contains('Class of 2022 - 2023, 26 students') - cy.contains('Showing 3 out of 26 students') - }) - }) - - it('Student progress data is shown correctly', () => { - const years = getEmptyYears(true) - const tableContents = [ - // [Year, All, < 30 credits, 30–60 credits, 60–90 credits, 90–120 credits, 120–150 credits, 150–180 credits, ≥ 180 credits, Graduated] - ...years.map(year => [year, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - ['2023 - 2024', 8, 8, 0, 0, 0, 0, 0, 0, 0], - ['2022 - 2023', 26, 9, 8, 4, 3, 0, 0, 0, 2], - ['2021 - 2022', 37, 8, 4, 9, 8, 4, 0, 0, 4], - ['2020 - 2021', 30, 2, 1, 2, 5, 0, 0, 1, 19], - ['2019 - 2020', 35, 1, 0, 2, 1, 0, 0, 4, 27], - ['2018 - 2019', 46, 0, 1, 1, 2, 0, 0, 2, 40], - ['2017 - 2018', 47, 0, 1, 3, 0, 0, 1, 0, 42], - ['Total', 229, 28, 15, 21, 19, 4, 1, 7, 134], - ] - - cy.checkTableStats(tableContents, 'study-programme-progress') - }) - - it('Progress section', () => { - cy.cs('programme-progress-bar-chart-section').scrollIntoView() - - cy.cs('programme-progress-bar-chart-section') - .should('contain', 'Less than 30 credits') - .should('contain', '30–60 credits') - .should('contain', 'At least 180 credits') - .should('contain', '58.5%') // The percentage for total graduated, to check that the graph renders - - cy.cs('programme-progress-bar-chart-section').contains('58.5%').hover() - cy.contains('Graduated: 134') - }) - - // CI contains different data than locally - it.skip('Average graduation times section', () => { - cy.cs('average-graduation-times-section').scrollIntoView() - - cy.cs('average-graduation-times-section').within(() => { - cy.cs('unset-graduation-times-section').within(() => { - cy.contains('2020 - 2021') - }) - - cy.get('text').contains('16').hover() - cy.contains('On time: 16') - - cy.cs('unset-graduation-times-section').within(() => { - cy.contains("Click a bar to view that year's study track level breakdown") - cy.get('text').contains('22').click() - }) - - cy.contains('Year 2019 - 2020 by start year') - - cy.get('text').contains('13').hover() - cy.contains('Matematiikka') - cy.contains('MAT-MAT') - cy.contains('On time: 13') - }) - - cy.cs('graduation-time-toggle').click() - - cy.cs('average-graduation-times-section').within(() => { - cy.contains('2020 - 2021') - cy.contains('19 graduated').hover() - cy.contains('From class of 2020 - 2021, 19/30 students have graduated') - cy.contains('median study time: 6 semesters') - cy.contains('16 graduated on time') - cy.contains('2 graduated max year overtime') - cy.contains('1 graduated over year late') - }) - }) - - describe('Study track can be changed', () => { - beforeEach(() => { - cy.wait('@stQuery') - cy.contains('All students of the programme') - cy.cs('study-track-select').click() - cy.contains('Ekonometria') - cy.contains('Tietojenkäsittelyteoria') - cy.contains('Tilastotiede') - cy.contains('Matematiikka').click() - }) - - it('Students of the study track are shown correctly', () => { - cy.cs('study-track-overview-section').contains('Students of the study track MAT-MAT by starting year') - const tableContents = [ - // [Year, All, Started studying, Present, Absent, Passive, Graduated, Has recent attainment, Men, Women, Other/Unknown, Finland, Other] - ['2022 - 2023', 3, 3, 0, 0, 1, 2, 0, 2, 1, 0, 3, 0], - ['2021 - 2022', 4, 1, 0, 0, 1, 3, 0, 3, 1, 0, 4, 0], - ['2020 - 2021', 13, 10, 0, 0, 1, 12, 0, 7, 6, 0, 12, 3], - ['2019 - 2020', 17, 14, 0, 0, 0, 17, 0, 10, 7, 0, 17, 1], - ['2018 - 2019', 24, 21, 0, 0, 2, 22, 0, 11, 13, 0, 24, 0], - ['2017 - 2018', 28, 24, 0, 0, 1, 27, 0, 15, 13, 0, 28, 0], - ['Total', 89, 73, 0, 0, 6, 83, 0, 48, 41, 0, 88, 4], - ] - cy.checkTableStats(tableContents, 'study-tracks-and-class-statistics') - }) - - it('Links to class statistics page with study track info included work', () => { - cy.cs('2020-population-link-button').first().click() - - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Studytrack MAT-MAT') - cy.contains('Class of 2020 - 2021, 30 students') - cy.contains('Showing 10 out of 30 students') - }) - - // FIXME: This feature was implemented. The data is no-good, so maybe reimplement this when it's clean. - it.skip('Info message about missing progress stats is displayed', () => { - cy.contains('Progress of students of the study track MAT-MAT by starting year') - cy.contains('Progress data is currently only available for all students of the degree programme.') - }) - - it.skip('Average graduation times are displayed correctly', () => { - cy.get("[data-cy='Section-averageGraduationTimesStudyTracks']") - cy.get("[data-cy='graduation-times-graph-breakdownBachelor']").within(() => { - cy.contains('Start year') - cy.contains('2020 - 2021') - cy.get('[aria-label="2020 - 2021, 9. On time."]').hover() - cy.contains('Graduated On time: 9 students') - }) - - cy.cs('graduation-time-toggle').click() - cy.cs('bachelor-median-time-bar-chart').within(() => { - cy.contains('Start year') - cy.contains('2020 - 2021') - cy.contains('12 graduated').hover() - cy.contains('From class of 2020 - 2021, 12/13 students have graduated') - cy.contains('median study time: 34 months') - cy.contains('9 graduated on time') - cy.contains('2 graduated max year overtime') - cy.contains('1 graduated over year late') - }) - }) - }) - }) - - describe('Programme courses tab works for basic user', () => { - beforeEach(() => { - cy.init('/study-programme') - cy.contains('a', 'Matemaattisten tieteiden kandiohjelma').click() - cy.cs('ProgrammeCoursesTab').click() - - cy.cs('by-credit-type-section') - cy.cs('by-credit-type-tab') - cy.cs('by-semester-tab') - }) - - describe('By credit type tab', () => { - beforeEach(() => { - cy.cs('show-credits-students-toggle').click() - cy.cs('year-toggle').click() - cy.get('thead').within(() => { - cy.get('tr') - .eq(0) - .within(() => { - cy.get('th').eq(3).click() - }) - }) - cy.get('tbody').within(() => { - cy.get('tr') - .eq(8) - .within(() => { - cy.get('td').eq(0).contains('Course') - cy.get('td').eq(1).contains('MAT11004') - cy.get('td').eq(2).contains('Differentiaalilaskenta') - cy.get('td').eq(3).contains('1240') - }) - }) - }) - - it('time range selection works', () => { - cy.cs('from-year-select').click() - cy.cs('from-year-select-option-2021').click() - cy.cs('to-year-select').click() - cy.cs('to-year-select-option-2022').click() - - cy.get('tbody').within(() => { - cy.get('tr') - .eq(9) - .within(() => { - cy.get('td').eq(0).contains('Course') - cy.get('td').eq(1).contains('MAT21009') - cy.get('td').eq(2).contains('Kandidaatintutkielma') - cy.get('td').eq(3).contains('414') - }) - }) - }) - - it('year toggle works', () => { - cy.cs('year-toggle').click() // Default view now Academic years - - cy.cs('from-year-select').click() - cy.cs('from-year-select-option-2017').click() - cy.cs('to-year-select').click() - cy.cs('to-year-select-option-2023').click() - - cy.get('tbody').within(() => { - cy.get('tr') - .eq(5) - .within(() => { - cy.get('td').eq(0).contains('Course') - cy.get('td').eq(1).contains('MAT11001') - cy.get('td').eq(2).contains('Johdatus yliopistomatematiikkaan') - cy.get('td').eq(3).contains('1265') - }) - }) - }) - - // TODO: Fix sorting / filters - it.skip('different sorting options work', () => { - cy.cs('CoursesSortableTable').within(() => { - // Course code - cy.get('th').eq(0).click() - cy.get('tr') - .eq(1) - .within(() => { - cy.get('td').eq(0).contains('odgi-zef0') - cy.get('td').eq(1).contains('Työ- ja organisaatiopsykologian perusopinnot') - }) - cy.get('th').eq(0).click() - cy.get('tr') - .eq(1) - .within(() => { - cy.get('td').eq(0).contains('MAT-yht') - cy.get('td').eq(1).contains('Muut opinnot') - }) - - // Course name - cy.get('th').eq(1).click() - cy.get('tr') - .eq(1) - .within(() => { - cy.get('td').eq(0).contains('MAT20003') - cy.get('td').eq(1).contains('Äidinkielen opinnot') - }) - cy.get('th').eq(1).click() - cy.get('tr') - .eq(1) - .within(() => { - cy.get('td').eq(0).contains('MAT11008') - cy.get('td').eq(1).contains('Advanced calculus') - }) - - // Total credits - cy.get('th').eq(2).click() - cy.get('tr') - .eq(1) - .within(() => { - cy.get('td').eq(0).contains('MAT110') - cy.get('td').eq(1).contains('Matematiikka, perusopinnot') - }) - cy.get('th').eq(2).click() - cy.get('tr') - .eq(1) - .within(() => { - cy.get('td').eq(0).contains('MAT20001') - cy.get('td').eq(1).contains('Kypsyysnäyte') - }) - }) - }) - - it("'Show credits/Show students' toggle works", () => { - cy.cs('year-toggle').click() - cy.wait(500) // So that the toggle has time to load - cy.get('thead tr') - .eq(0) - .within(() => { - cy.get('th').should('have.length', 6) - const headers = ['Type', 'Code', 'Name', 'Total credits', 'Credits produced by', 'Transferred credits'] - headers.forEach((header, index) => { - cy.get('th').eq(index).contains(header) - }) - }) - cy.get('thead tr') - .eq(1) - .within(() => { - cy.get('th').should('have.length', 7) - const headers = [ - 'Degree students', - 'Open university (hetu)', - 'Open university (no hetu)', - 'Exchange students', - 'Other universities', - 'Separate studies', - 'Other', - ] - headers.forEach((header, index) => { - cy.get('th').eq(index).contains(header) - }) - }) - - cy.cs('show-credits-students-toggle').click() - - cy.get('thead tr') - .eq(0) - .within(() => { - cy.get('th').should('have.length', 7) - const headers = [ - 'Type', - 'Code', - 'Name', - 'Total students', - 'Breakdown of total', - 'Breakdown of passed', - 'Not included in total or passed', - ] - headers.forEach((header, index) => { - cy.get('th').eq(index).contains(header) - }) - }) - cy.get('thead tr') - .eq(1) - .within(() => { - cy.get('th').should('have.length', 10) - const headers = [ - 'Passed', - 'Not completed', - 'Degree students', - 'Open university students (with hetu)', - 'Open university students (without hetu)', - 'Exchange students', - 'Other university students', - 'Separate studies', - 'Other students', - 'Students with transferred credits', - ] - headers.forEach((header, index) => { - cy.get('th').eq(index).contains(header) - }) - }) - - cy.get('tbody').within(() => { - cy.get('tr') - .eq(5) - .within(() => { - cy.get('td').eq(0).contains('Course') - cy.get('td').eq(1).contains('MAT11001') - cy.get('td').eq(2).contains('Johdatus yliopistomatematiikkaan') - cy.get('td').eq(3).contains('272') - }) - }) - }) - }) - - describe('By semester tab', () => { - beforeEach(() => { - cy.cs('by-semester-tab').click() - }) - - // FIXME: Flaky - it.skip('test', () => { - // TODO: Implement some real tests for this tab - cy.contains('From') - }) - }) - }) - - describe('Degree courses tab works for basic user', () => { - beforeEach(() => { - cy.init('/study-programme') - cy.contains('a', 'Matemaattisten tieteiden kandiohjelma').click() - cy.cs('DegreeCoursesTab').click() - }) - - it('Curriculum section', () => { - cy.cs('curriculum-section') - cy.contains('Select curriculum to edit:') - cy.cs('curriculum-picker').contains('2023–2026') - // TODO: Test changing the curriculum - }) - - describe('Credit criteria section', () => { - it('info box', () => { - cy.cs('credit-criteria-section') - cy.cs('credit-criteria-info-box-button').click() - cy.cs('credit-criteria-info-box-content').contains('Here you can change') - }) - - it.skip('changing the credit criteria works', () => { - // TODO: Test using the inputs - // TODO: Button status - // TODO: Test "previously set to _" text changing when saving - }) - }) - - it('Degree course table', () => { - cy.cs('degree-course-table') - // TODO: Test clicking the arrow buttons - // TODO: Test toggling visibility for MODULES and COURSES - // TODO: Test changing criterion labels - }) - }) - - describe('Tags tab works for basic user', () => { - beforeEach(() => { - cy.init('/study-programme') - cy.contains('a', 'Matemaattisten tieteiden kandiohjelma').click({ force: true }) - cy.cs('TagsTab').click() - }) - - it('info box', () => { - cy.cs('create-new-tag-info-box-button').click() - cy.cs('create-new-tag-info-box-content').contains('Here you can create') - }) - - describe('Adding tags to populations and removing them works', () => { - beforeEach(() => { - cy.contains('This degree programme does not have any tags yet') - cy.cs('tag-name-text-field').type(tagName) - }) - - afterEach(() => { - deleteTag(tagName) - cy.contains('This degree programme does not have any tags yet') - }) - - it('can create and delete tags without start year', () => { - cy.cs('create-button').click() - cy.contains(tagName) - cy.contains('No associated start year') - }) - - it.skip('can create and delete tags with start year', () => { - // TODO: This test fails in the pipeline, but works locally. Investigate. - selectYear('2022') - cy.cs('create-button').click() - cy.contains(tagName) - cy.contains('Associated start year 2022') - }) - - it.skip('population link works', () => { - // TODO: This test fails in the pipeline, but works locally. Investigate. - selectYear('2022') - cy.cs('create-button').click() - cy.contains(tagName) - cy.cs('population-link-button').click() - cy.contains(`Tagged with: ${tagName}`) - cy.go('back') - }) - - it('can create personal tags', () => { - cy.cs('personal-tag-toggle').click() - cy.cs('create-button').click() - cy.contains(tagName) - cy.cs(`${tagName}-visibility-icon`) - }) - }) - - describe('Adding tags to students and removing them works', () => { - const studentInput = '477806,478275; 478953 479239\n 480080' - const studentNumbers = studentInput.match(/[^\s,;]+/g) - - it.skip('can add tags to students', () => { - // TODO: This test fails in the pipeline, but works locally. Investigate. - cy.cs('tag-name-text-field').type(tagName) - selectYear('2022') - cy.cs('create-button').click() - cy.contains(tagName) - - cy.cs('add-students-button').click() - cy.cs('add-students-text-field').type(studentInput) - cy.cs('add-students-confirm-button').click() - cy.contains('Students added to tag') - - cy.cs('population-link-button').click() - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Class of 2022 - 2023') - cy.contains(`Tagged with: ${tagName}`) - cy.contains('Students (5)') - .parent() - .then($parentDiv => { - if (!$parentDiv.hasClass('active')) cy.contains('Students (5)').click() - }) - - for (const studentNumber of studentNumbers) { - cy.contains(studentNumber) - } - - for (const studentNumber of studentNumbers) { - cy.visit(`/students/${studentNumber}`) - cy.contains('Tags') - cy.contains(tagName) - } - - cy.get('a').contains('Matemaattisten tieteiden kandiohjelma').invoke('removeAttr', 'target').click() - cy.url().should('include', '/study-programme/KH50_001?tab=4') - - deleteTag(tagName) - }) - - it('deleting a tag from tag view also removes it from students', () => { - cy.contains(tagName).should('not.exist') - for (const studentNumber of studentNumbers) { - cy.visit(`/students/${studentNumber}`) - cy.contains('Tags').should('not.exist') - cy.contains(tagName).should('not.exist') - } - }) - }) - }) - - describe('IAM user', () => { - beforeEach(() => { - cy.init('/study-programme', 'onlyiamrights') - cy.contains('a', 'Matemaattisten tieteiden kandiohjelma').click() - }) - - it.skip('year selector', () => { - // TODO: Implement this test - // Things to test: - // - Clicking the button works - // - Selecting a study track works - // - The button is disabled if only one year is selected - // - The slider is not visible if the user does not have correct programme rights - }) - - it('can access programme and correct tabs are visible', () => { - cy.contains('Basic information') - cy.contains('Study tracks and class statistics') - - cy.contains('Update statistics').should('not.exist') - cy.contains('Degree courses').should('not.exist') - }) - - it('can access basic information', () => { - cy.cs('BasicInformationTab').click() - - cy.cs('students-of-the-study-programme-section') - cy.cs('credits-produced-by-the-study-programme-section') - cy.cs('graduated-and-thesis-writers-of-the-programme-section') - cy.cs('average-graduation-times-section') - cy.cs('programmes-before-or-after-section') - }) - - it('can access study tracks', () => { - cy.cs('StudyTracksAndClassStatisticsTab').click() - - cy.cs('study-track-overview-section') - cy.cs('progress-of-students-section') - cy.cs('average-graduation-times-section') - }) - - it("doesn't see other tabs", () => { - cy.cs('DegreeCoursesTab').should('not.exist') - cy.cs('TagsTab').should('not.exist') - cy.cs('UpdateStatisticsTab').should('not.exist') - }) - }) -}) diff --git a/cypress/e2e/Faculty_statistics.js b/cypress/e2e/Faculty_statistics.js deleted file mode 100644 index 2941f780c..000000000 --- a/cypress/e2e/Faculty_statistics.js +++ /dev/null @@ -1,287 +0,0 @@ -/// - -const path = require('path') - -const timestamp = new Date().toLocaleDateString('en-CA', { year: 'numeric', month: '2-digit', day: '2-digit' }) // YYYY-MM-DD, taking the local time zone into account -const downloadsFolder = Cypress.config('downloadsFolder') - -describe('Faculty statistics', () => { - describe('Faculty list', () => { - beforeEach(() => { - cy.init('/faculties') - }) - - it('contains faculty names and faculty codes', () => { - cy.contains('Faculties') - cy.contains('Teologinen tiedekunta') - cy.contains('H10') - cy.contains('Oikeustieteellinen tiedekunta') - cy.contains('H20') - cy.contains('Lääketieteellinen tiedekunta') - cy.contains('H30') - cy.contains('Humanistinen tiedekunta') - cy.contains('H40') - cy.contains('Matemaattis-luonnontieteellinen tiedekunta') - cy.contains('H50') - cy.contains('Farmasian tiedekunta') - cy.contains('H55') - cy.contains('Bio- ja ympäristötieteellinen tiedekunta') - cy.contains('H57') - cy.contains('Kasvatustieteellinen tiedekunta') - cy.contains('H60') - cy.contains('Valtiotieteellinen tiedekunta') - cy.contains('H70') - cy.contains('Svenska social- och kommunalhögskolan') - cy.contains('H74') - cy.contains('Maatalous-metsätieteellinen tiedekunta') - cy.contains('H80') - cy.contains('Eläinlääketieteellinen tiedekunta') - cy.contains('H90') - }) - - it('contains a working link to faculty page', () => { - cy.contains('Faculties') - cy.contains('a', 'Teologinen tiedekunta').click() - cy.location('pathname').should('eq', '/faculties/hy-org-1000000580') - cy.contains('Teologinen tiedekunta') - cy.contains('H10') - }) - }) - - describe('Basic information tab', () => { - describe('Admin user', () => { - beforeEach(() => { - cy.init('/faculties', 'admin') - cy.contains('a', 'Eläinlääketieteellinen tiedekunta').click() - }) - - it('Correct tabs are shown', () => { - cy.cs('faculty-tabs').should('contain', 'Basic information') - cy.cs('faculty-tabs').should('contain', 'Students by starting year') - cy.cs('faculty-tabs').should('contain', 'Graduation times') - cy.cs('faculty-tabs').should('contain', 'Update statistics') - }) - }) - - describe('Basic user', () => { - beforeEach(() => { - cy.init('/faculties') - cy.contains('a', 'Matemaattis-luonnontieteellinen tiedekunta').click() - }) - - describe('Info boxes', () => { - it('Students of the faculty', () => { - cy.cs('students-of-the-faculty-info-box-button').click() - cy.cs('students-of-the-faculty-info-box-content').contains('Taulukon luvut on') - }) - - it('Graduated of the faculty', () => { - cy.cs('graduated-of-the-faculty-info-box-button').click() - cy.cs('graduated-of-the-faculty-info-box-content').contains('Sisältää kyseisenä') - }) - - it('Thesis writers of the faculty', () => { - cy.cs('thesis-writers-of-the-faculty-info-box-button').click() - cy.cs('thesis-writers-of-the-faculty-info-box-content').contains('Sisältää kyseisenä') - }) - - it('Credits produced by the faculty', () => { - cy.cs('credits-produced-by-the-faculty-info-box-button').click() - cy.cs('credits-produced-by-the-faculty-info-box-content').contains('Sisältää opintopisteet') - }) - }) - - it('All graphs and tables are shown', () => { - cy.cs('students-of-the-faculty-line-graph-section').should('be.visible') - cy.cs('students-of-the-faculty-interactive-data-table').should('be.visible') - cy.cs('graduated-of-the-faculty-line-graph-section').should('be.visible') - cy.cs('graduated-of-the-faculty-interactive-data-table').should('be.visible') - cy.cs('thesis-writers-of-the-faculty-line-graph-section').should('be.visible') - cy.cs('thesis-writers-of-the-faculty-interactive-data-table').should('be.visible') - cy.cs('credits-produced-by-the-faculty-stacked-bar-chart-section').should('be.visible') - cy.cs('credits-produced-by-the-faculty-interactive-data-table').should('be.visible') - }) - - it('Correct tabs are shown', () => { - cy.cs('faculty-tabs').should('contain', 'Basic information') - cy.cs('faculty-tabs').should('contain', 'Students by starting year') - cy.cs('faculty-tabs').should('contain', 'Graduation times') - cy.cs('faculty-tabs').should('not.contain', 'Update statistics') - }) - - it('Toggle years works', () => { - cy.cs('credits-produced-by-the-faculty-interactive-data-table').should('contain', '2022 - 2023') - cy.cs('thesis-writers-of-the-faculty-interactive-data-table').should('contain', '2022 - 2023') - cy.cs('students-of-the-faculty-interactive-data-table').should('contain', '2022 - 2023') - cy.cs('graduated-of-the-faculty-interactive-data-table').should('contain', '2022 - 2023') - cy.cs('year-toggle').click() - cy.cs('credits-produced-by-the-faculty-interactive-data-table').should('contain', '2022') - cy.cs('thesis-writers-of-the-faculty-interactive-data-table').should('contain', '2022') - cy.cs('students-of-the-faculty-interactive-data-table').should('contain', '2022') - cy.cs('graduated-of-the-faculty-interactive-data-table').should('contain', '2022') - }) - - it('Toggle programmes works', () => { - cy.cs('faculty-programmes-shown-info').should('not.exist') - cy.cs('programme-toggle').click() - cy.cs('faculty-programmes-shown-info').should('be.visible') - }) - - it('Toggle study rights works', () => { - cy.cs('faculty-exclude-specials-info').should('not.exist') - cy.cs('study-right-toggle').click() - cy.cs('faculty-exclude-specials-info').should('be.visible') - }) - - it.skip('Data can be exported to Excel files', { retries: 2 }, () => { - // TODO: Fix this test - const sections = [ - 'StudentsOfTheFaculty', - 'GraduatedOfTheFaculty', - 'ThesisWritersOfTheFaculty', - 'CreditsProducedByTheFaculty', - ] - sections.forEach(section => { - cy.cs(`${section}Graph`).within(() => { - cy.get('[aria-label="View chart menu, Chart"]').click({ force: true }) - cy.contains('li.highcharts-menu-item', 'Download XLS').click() - const downloadedFile = `oodikone_${section}_H50_${timestamp}.xls` - cy.readFile(path.join(downloadsFolder, downloadedFile)) - }) - }) - }) - }) - }) - - describe('Students by starting year tab', () => { - beforeEach(() => { - cy.init('/faculties') - cy.contains('a', 'Matemaattis-luonnontieteellinen tiedekunta').click() - cy.contains('Students by starting year').click() - }) - - it('Export button', { retries: 2 }, () => { - cy.cs('faculty-student-table-export-button').should('be.visible').and('not.be.disabled').click() - const downloadedFile = `oodikone_H50_programme_stats_${timestamp}.xlsx` - cy.readFile(path.join(downloadsFolder, downloadedFile)) - }) - - it('Info box', () => { - cy.cs('faculty-student-table-info-box-button').click() - cy.cs('faculty-student-table-info-box-content').contains('Opiskelijat, joiden') - }) - - it.skip('Study right toggle', () => { - // TODO: Implement - }) - - it.skip('Graduated toggle', () => { - // TODO: Implement - }) - - it.skip('Hoverable country list', () => { - // TODO: Implement - }) - - it.skip('Expandable rows', () => { - // TODO: Implement - }) - - it.skip('Population links', () => { - // TODO: Implement - }) - - it('Percentage toggle works', () => { - cy.cs('faculty-student-stats-table').should('be.visible') - cy.cs('faculty-student-stats-table').should('not.contain', '92.3 %') - cy.cs('percentage-toggle').click() - cy.cs('faculty-student-stats-table').should('contain', '92.3 %') - }) - }) - - describe('Progress tab', () => { - beforeEach(() => { - cy.init('/faculties') - cy.contains('a', 'Matemaattis-luonnontieteellinen tiedekunta').click() - cy.contains('Progress').click() - }) - - it.skip('Export button', { retries: 2 }, () => { - // TODO: Fix this test - cy.cs('FacultyProgress-export-button').should('be.visible').and('not.be.disabled').click() - const downloadedFile = `oodikone_H50_progress_tab_${timestamp}.xlsx` - cy.readFile(path.join(downloadsFolder, downloadedFile)) - }) - - it.skip('Info boxes', () => { - cy.cs('FacultyProgress-info-box-button').click() - cy.cs('FacultyProgress-info-box-content').contains('Kuvaa tiedekuntaan') - // TODO: Click open the accordion first - cy.cs('BachelorMastersProgress-info-box-button').click() - cy.cs('BachelorMastersProgress-info-box-content').contains('The starting year is the') - }) - - it.skip('Progress bar charts exist', () => { - // TODO: Click open the accordion first - cy.cs('FacultyBachelorsProgressBarChart').should('be.visible') - cy.cs('FacultyBachelorMastersProgressBarChart').should('be.visible') - cy.cs('FacultyMastersProgressBarChart').should('be.visible') - cy.cs('FacultyBachelorsProgressBarChart').should('be.visible') - }) - - it.skip('Progress tables exist', () => { - // TODO: Click open the accordion first - cy.cs('FacultyBachelorsProgressTable').should('be.visible') - cy.cs('FacultyBachelorMasterProgressTable').should('be.visible') - cy.cs('FacultyMastersProgressTable').should('be.visible') - cy.cs('FacultyBachelorsProgressTable').should('be.visible') - }) - - it.skip('Graduated toggle', () => { - // TODO: Implement - }) - - it.skip('Study right toggle', () => { - // TODO: Implement - }) - }) - - describe('Graduation times tab', () => { - beforeEach(() => { - cy.init('/faculties') - cy.contains('a', 'Matemaattis-luonnontieteellinen tiedekunta').click() - cy.contains('Graduation times').click() - }) - - it.skip('Export button', { retries: 2 }, () => { - // TODO: Fix this test - cy.cs('average-graduation-times-export-button').should('be.visible').and('not.be.disabled').click() - const downloadedFile = `oodikone_H50_graduation_times_${timestamp}.xlsx` - cy.readFile(path.join(downloadsFolder, downloadedFile)) - }) - - it('Info boxes', () => { - cy.cs('average-graduation-times-info-box-button').click() - cy.cs('average-graduation-times-info-box-content').contains('Opiskelijoiden keskimääräiset') - }) - - it.skip('Study times toggle', () => { - // TODO: Implement - }) - - it.skip('Year toggle', () => { - // TODO: Implement - }) - - it.skip('Degree programme toggle', () => { - // TODO: Implement - }) - - it('Graphs are visible', () => { - cy.cs('bachelor-graduation-times-section').should('be.visible') - // ! No test data for bachelor + master - cy.cs('master-graduation-times-section').should('be.visible') - cy.cs('doctor-graduation-times-section').should('be.visible') - }) - }) -}) diff --git a/cypress/e2e/Filters.js b/cypress/e2e/Filters.js deleted file mode 100644 index 2976e8fef..000000000 --- a/cypress/e2e/Filters.js +++ /dev/null @@ -1,468 +0,0 @@ -/// - -const setClockToMockedDate = () => { - const MOCKED_DATE = new Date('2024-08-30') - cy.clock(MOCKED_DATE, ['Date']) -} - -const checkFilteredStudentCount = studentCount => { - cy.contains(`Students (${studentCount})`) -} - -describe("Population statistics with a master's programme", { testIsolation: false }, () => { - const pathToMathMSc2020 = '/populations?years=2020&programme=MH50_001&semesters=FALL&semesters=SPRING' - const defaultAmountOfStudents = 26 - const expectedBaMaStudents = 24 - const expectedMasterOnlyStudents = 2 - - before(() => cy.init(pathToMathMSc2020)) - - it('Study track filter works', () => { - cy.cs('studyTrackFilter-header').click() - cy.selectFromDropdown('studyTrackFilter', 'Matematiikka ja soveltava matematiikka (MAST-MSM)', true) - checkFilteredStudentCount(15) - - cy.cs('studyTrackFilter-clear').click() - cy.cs('studyTrackFilter-header').click() - }) - - it('Study right type filter works', () => { - cy.cs('studyRightTypeFilter-header').click() - cy.get('input[name="studyRightTypeFilter"][value="0"]').should('be.checked') - - // Bachelor + master - cy.get('input[name="studyRightTypeFilter"][value="1"]').click() - cy.get('input[name="studyRightTypeFilter"][value="1"]').should('be.checked') - checkFilteredStudentCount(expectedBaMaStudents) - // Master only - cy.get('input[name="studyRightTypeFilter"][value="2"]').click() - cy.get('input[name="studyRightTypeFilter"][value="2"]').should('be.checked') - checkFilteredStudentCount(expectedMasterOnlyStudents) - // All - cy.get('input[name="studyRightTypeFilter"][value="0"]').click() - cy.get('input[name="studyRightTypeFilter"][value="0"]').should('be.checked') - checkFilteredStudentCount(defaultAmountOfStudents) - - cy.cs('studyRightTypeFilter-header').click() - }) -}) - -describe.skip('Population Statistics', { testIsolation: false }, () => { - const pathToMathBSc2020 = '/populations?years=2020&programme=KH50_001&semesters=FALL&semesters=SPRING' - const defaultAmountOfStudents = 27 - const graduated = 16 - const transferred = 3 - - before(() => cy.init(pathToMathBSc2020)) - beforeEach(() => setClockToMockedDate()) - - it.skip('Study right type filter is not visible', () => { - cy.contains('Study right type').should('not.exist') - }) - - // TODO: FilterRadio is not working correcly - it.skip('Transfer filter works and is set to "not transferred" by default', () => { - cy.cs('transferredToProgrammeFilter-filter-card').should('have.attr', 'data-active', 'true') - cy.get('input[name="transferredToProgrammeFilter"][value="Not transferred"]').should('be.checked') - checkFilteredStudentCount(defaultAmountOfStudents) - - cy.cs('transferredToProgrammeFilter-filter-card').should('have.attr', 'data-active', 'true') - cy.get('input[name="transferredToProgrammeFilter"][value="Not transferred"]').should('be.checked') - checkFilteredStudentCount(defaultAmountOfStudents) - - cy.get('input[name="transferredToProgrammeFilter"][value="Transferred"]').click() - cy.get('input[name="transferredToProgrammeFilter"][value="Transferred"]').should('be.checked') - checkFilteredStudentCount(transferred) - - cy.get('input[name="transferredToProgrammeFilter"][value="All"]').click() - cy.get('input[name="transferredToProgrammeFilter"][value="All"]').should('be.checked') - checkFilteredStudentCount(defaultAmountOfStudents + transferred) - - cy.get('input[name="transferredToProgrammeFilter"][value="Not transferred"]').click() - cy.get('input[name="transferredToProgrammeFilter"][value="Not transferred"]').should('be.checked') - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Graduation filter works', () => { - cy.cs('graduatedFromProgrammeFilter-header').click() - - cy.get('input[name="graduatedFromProgrammeFilter"][value="1"]').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="1"]').should('be.checked') - checkFilteredStudentCount(graduated) - - cy.get('input[name="graduatedFromProgrammeFilter"][value="-1"]').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="-1"]').should('be.checked') - checkFilteredStudentCount(defaultAmountOfStudents - graduated) - - cy.get('input[name="graduatedFromProgrammeFilter"][value="0"]').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="0"]').should('be.checked') - checkFilteredStudentCount(defaultAmountOfStudents) - - cy.cs('graduatedFromProgrammeFilter-header').click() - }) - - it('Enrollment filter works', () => { - cy.cs('enrollmentStatusFilter-header').click() - cy.selectFromDropdown('enrollmentStatusFilter-status', 0) - cy.selectFromDropdown('enrollmentStatusFilter-semester', 'Syksy 2023', true) - checkFilteredStudentCount(25) - - cy.cs('enrollmentStatusFilter-clear').click() - cy.cs('enrollmentStatusFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Credit filter works', () => { - cy.cs('creditsEarnedFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - cy.setRangeSelect('creditsEarnedFilter', 50, 150, 12) - - cy.cs('creditsEarnedFilter-clear').click() - cy.cs('creditsEarnedFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Age filter works', () => { - cy.cs('ageFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - cy.setRangeSelect('ageFilter', 23, 30, 21) - - cy.cs('ageFilter-clear').click() - cy.cs('ageFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Gender filter works', () => { - cy.cs('genderFilter-header').click() - cy.selectFromDropdown('genderFilter', 0) - checkFilteredStudentCount(13) - cy.selectFromDropdown('genderFilter', 1) - checkFilteredStudentCount(14) - cy.selectFromDropdown('genderFilter', 2) - checkFilteredStudentCount(0) - cy.selectFromDropdown('genderFilter', 3) - checkFilteredStudentCount(0) - - cy.cs('genderFilter-clear').click() - cy.cs('genderFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Starting year filter works', () => { - cy.cs('startYearAtUniFilter-header').click() - cy.selectFromDropdown('startYearAtUniFilter', 0) - checkFilteredStudentCount(1) - cy.selectFromDropdown('startYearAtUniFilter', 7) - checkFilteredStudentCount(21) - - cy.cs('startYearAtUniFilter-clear').click() - cy.cs('startYearAtUniFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Admission type filter works', () => { - cy.cs('admissionTypeFilter-header').click() - cy.selectFromDropdown('admissionTypeFilter', 0) - checkFilteredStudentCount(18) - cy.selectFromDropdown('admissionTypeFilter', 1) - checkFilteredStudentCount(6) - - cy.cs('admissionTypeFilter-clear').click() - cy.cs('admissionTypeFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Courses filter works', () => { - const courses = [ - { code: 'MAT21012', name: 'Differentiaaliyhtälöt I' }, - { code: 'MFK-M204', name: 'Matematiikkaa kaikkialla' }, - ] - - cy.cs('courseFilter-header').click() - cy.selectFromAutocomplete('courseFilter', `${courses[0].code} - ${courses[0].name}`) - checkFilteredStudentCount(9) - cy.selectFromDropdown(`courseFilter-${courses[0].code}`, 1) - checkFilteredStudentCount(7) - cy.selectFromAutocomplete('courseFilter', `${courses[1].code} - ${courses[1].name}`) - checkFilteredStudentCount(6) - cy.selectFromDropdown(`courseFilter-${courses[1].code}`, 1) - checkFilteredStudentCount(4) - - cy.cs(`courseFilter-${courses[1].code}-clear`).click() - checkFilteredStudentCount(7) - - cy.cs('courseFilter-clear').click() - cy.cs('courseFilter-header').click() - - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Filter combinations work', () => { - checkFilteredStudentCount(defaultAmountOfStudents) - - cy.cs('graduatedFromProgrammeFilter-header').click() - - cy.get('input[name="graduatedFromProgrammeFilter"][value="1"]').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="1"]').should('be.checked') - checkFilteredStudentCount(graduated) - - cy.cs('ageFilter-header').click() - cy.setRangeSelect('ageFilter', 23, 30, 12) - - cy.cs('graduatedFromProgrammeFilter-clear').click() - cy.cs('graduatedFromProgrammeFilter-header').click() - cy.cs('ageFilter-clear').click() - cy.cs('ageFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('"Reset All Filters" button works', () => { - cy.cs('genderFilter-header').click() - cy.selectFromDropdown('genderFilter', 0) - checkFilteredStudentCount(13) - cy.cs('startYearAtUniFilter-header').click() - cy.selectFromDropdown('startYearAtUniFilter', 7) - checkFilteredStudentCount(8) - - cy.cs('reset-all-filters').click() - cy.cs('genderFilter-header').click() - cy.cs('startYearAtUniFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) -}) - -describe('Population Statistics with Bachelor + Master', { testIsolation: false }, () => { - const pathToMathBSc2017 = - '/populations?years=2017&programme=KH50_001&showBachelorAndMaster=true&semesters=FALL&semesters=SPRING' - const defaultAmountOfStudents = 47 - - before(() => cy.init(pathToMathBSc2017)) - - it('Graduation filter works', () => { - cy.cs('graduatedFromProgrammeFilter-header').click() - - cy.get('input[name="graduatedFromProgrammeFilter"][value="1"]').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="1"]').should('be.checked') - checkFilteredStudentCount(42) - cy.get('input[name="graduatedFromProgrammeFilter"][value="2"]').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="2"]').should('be.checked') - checkFilteredStudentCount(18) - cy.get('input[name="graduatedFromProgrammeFilter"][value="-1"]').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="-1"]').should('be.checked') - checkFilteredStudentCount(5) - cy.get('input[name="graduatedFromProgrammeFilter"][value="-2"]').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="-2"]').should('be.checked') - checkFilteredStudentCount(29) - - cy.cs('graduatedFromProgrammeFilter-clear').click() - cy.cs('graduatedFromProgrammeFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Study right status filter works', () => { - checkFilteredStudentCount(defaultAmountOfStudents) - cy.cs('studyRightStatusFilter-header').click() - - // Bachelor - cy.get('input[name="studyRightStatusFilter"][value="Active Bachelor study right"]').click() - cy.get('input[name="studyRightStatusFilter"][value="Active Bachelor study right"]').should('be.checked') - checkFilteredStudentCount(0) - // Master (combined) - cy.get('input[name="studyRightStatusFilter"][value="Active Master study right"]').click() - cy.get('input[name="studyRightStatusFilter"][value="Active Master study right"]').should('be.checked') - checkFilteredStudentCount(0) - - // Non-Bachelor - cy.get('input[name="studyRightStatusFilter"][value="Passive Bachelor study right"]').click() - cy.get('input[name="studyRightStatusFilter"][value="Passive Bachelor study right"]').should('be.checked') - checkFilteredStudentCount(5) - // Non-Master (combined) - cy.get('input[name="studyRightStatusFilter"][value="Passive Master study right"]').click() - cy.get('input[name="studyRightStatusFilter"][value="Passive Master study right"]').should('be.checked') - checkFilteredStudentCount(24) - - cy.cs('studyRightStatusFilter-clear').click() - cy.cs('studyRightStatusFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) -}) - -// FIXME: Flaky -describe.skip('Course Statistics', { testIsolation: false }, () => { - const pathToLimits2021 = - '/coursepopulation?coursecodes=%5B"MAT11003"%2C"57116"%2C"57016"%2C"AYMAT11003"%5D&from=72&separate=false&to=72&unifyCourses=unifyStats' - const defaultAmountOfStudents = 48 - - before(() => cy.init(pathToLimits2021)) - beforeEach(() => setClockToMockedDate()) - - it('Grade filter works', () => { - checkFilteredStudentCount(defaultAmountOfStudents) - cy.cs('gradeFilter-header').click() - - cy.cs('gradeFilter-5').click() - checkFilteredStudentCount(23) - cy.cs('gradeFilter-3').click() - checkFilteredStudentCount(29) - cy.cs('gradeFilter-3').click() - cy.cs('gradeFilter-5').click() - - cy.cs('gradeFilter-clear').should('not.exist') - - cy.cs('gradeFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Programme filter works and defaults to "Attainment"', () => { - checkFilteredStudentCount(defaultAmountOfStudents) - cy.cs('programmeFilter-header').click() - cy.cs('programmeFilter-mode-selector').children().eq(0).should('contain', 'Attainment') - cy.selectFromDropdown('programmeFilter', 1, true) - checkFilteredStudentCount(33) - - cy.cs('programmeFilter-clear').click() - cy.cs('programmeFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Age filter works', () => { - cy.cs('ageFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - cy.setRangeSelect('ageFilter', 23, 30, 36) - - cy.cs('ageFilter-clear').click() - cy.cs('ageFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Gender filter works', () => { - cy.cs('genderFilter-header').click() - cy.selectFromDropdown('genderFilter', 0) - checkFilteredStudentCount(9) - cy.selectFromDropdown('genderFilter', 1) - checkFilteredStudentCount(39) - cy.selectFromDropdown('genderFilter', 2) - checkFilteredStudentCount(0) - cy.selectFromDropdown('genderFilter', 3) - checkFilteredStudentCount(0) - - cy.cs('genderFilter-clear').click() - cy.cs('genderFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Starting year filter works', () => { - cy.cs('startYearAtUniFilter-header').click() - cy.selectFromDropdown('startYearAtUniFilter', 0) - checkFilteredStudentCount(1) - cy.selectFromDropdown('startYearAtUniFilter', 10) - checkFilteredStudentCount(24) - - cy.cs('startYearAtUniFilter-clear').click() - cy.cs('startYearAtUniFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Filter combinations work', () => { - cy.cs('ageFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - cy.setRangeSelect('ageFilter', 23, 30, 36) - - cy.cs('gradeFilter-header').click() - cy.cs('gradeFilter-5').click() - checkFilteredStudentCount(17) - - cy.cs('gradeFilter-clear').click() - cy.cs('gradeFilter-header').click() - cy.cs('ageFilter-clear').click() - cy.cs('ageFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) -}) - -describe('Custom Population Statistics', { testIsolation: false }, () => { - let defaultAmountOfStudents - - before(() => { - cy.init('/custompopulation') - cy.fixture('customPopulations').then(({ studentNumbersForCSStudentsSet1, studentNumbersForCSStudentsSet2 }) => { - const students = [...studentNumbersForCSStudentsSet1, ...studentNumbersForCSStudentsSet2] - defaultAmountOfStudents = students.length - cy.cs('student-number-input').click() - cy.cs('student-number-input').type(students.join('{enter}')) - cy.cs('search-button').click() - }) - }) - beforeEach(() => setClockToMockedDate()) - - it('Age filter works', () => { - cy.cs('ageFilter-header').click() - cy.setRangeSelect('ageFilter', 24, 28, 5) - - cy.cs('ageFilter-clear').click() - cy.cs('ageFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Programme filter works and defaults to "Active Study Right"', () => { - cy.cs('programmeFilter-header').click() - cy.cs('programmeFilter-mode-selector').children().eq(0).should('contain', 'Active Study Right') - cy.selectFromDropdown('programmeFilter', 1, true) - checkFilteredStudentCount(3) - - cy.cs('programmeFilter-clear').click() - cy.cs('programmeFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Gender filter works', () => { - cy.cs('genderFilter-header').click() - cy.selectFromDropdown('genderFilter', 0) - checkFilteredStudentCount(5) - cy.selectFromDropdown('genderFilter', 1) - checkFilteredStudentCount(3) - cy.selectFromDropdown('genderFilter', 2) - checkFilteredStudentCount(0) - cy.selectFromDropdown('genderFilter', 3) - checkFilteredStudentCount(0) - - cy.cs('genderFilter-clear').click() - cy.cs('genderFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Starting year filter works', () => { - cy.cs('startYearAtUniFilter-header').click() - cy.selectFromDropdown('startYearAtUniFilter', 0) - checkFilteredStudentCount(2) - - cy.cs('startYearAtUniFilter-clear').click() - cy.cs('startYearAtUniFilter-header').click() - checkFilteredStudentCount(defaultAmountOfStudents) - }) - - it('Courses filter works', () => { - const courses = [ - { code: 'MAT11005', name: 'Integraalilaskenta' }, - { code: 'MAT21007', name: 'Mitta ja integraali' }, - ] - - cy.cs('courseFilter-header').click() - cy.selectFromAutocomplete('courseFilter', `${courses[0].code} - ${courses[0].name}`) - checkFilteredStudentCount(7) - cy.selectFromDropdown(`courseFilter-${courses[0].code}`, 1) - checkFilteredStudentCount(6) - cy.selectFromAutocomplete('courseFilter', `${courses[1].code} - ${courses[1].name}`) - checkFilteredStudentCount(6) - cy.selectFromDropdown(`courseFilter-${courses[1].code}`, 3) - checkFilteredStudentCount(6) - - cy.cs(`courseFilter-${courses[1].code}-clear`).click() - checkFilteredStudentCount(6) - - cy.cs('courseFilter-clear').click() - cy.cs('courseFilter-header').click() - - checkFilteredStudentCount(defaultAmountOfStudents) - }) -}) diff --git a/cypress/e2e/Language_center.js b/cypress/e2e/Language_center.js deleted file mode 100644 index 48cb58fba..000000000 --- a/cypress/e2e/Language_center.js +++ /dev/null @@ -1,89 +0,0 @@ -/// - -const chooseSemester = (semester, fromOrTo) => { - cy.cs(`semester-${fromOrTo}`).click() - cy.cs(`select-opt-${semester}`).click() - cy.cs(`select-opt-${semester}`).should('not.have.class', 'visible') -} - -const checkNumbers = (numbers, numberOfColumns, mode) => { - const offset = 1 // skip first col with codes / names - cy.cs(`ooditable-${mode}`).find('table').find('tbody').as('tbody') - cy.get('@tbody').find('tr').first().as('totalRow') - cy.get('@totalRow').find('td').should('have.length', numberOfColumns) - cy.get('@totalRow').find('td').eq(0).should('contain', 'All courses total') - - numbers.forEach((number, index) => { - cy.get('@totalRow') - .find('td') - .eq(index + offset) - .should('contain', number) - }) -} - -describe('When language center is opened', () => { - describe('as an admin user', () => { - beforeEach(() => { - cy.init('/languagecenterview', 'admin') - cy.cs('completions-button').click() - }) - - describe('Faculties tab', () => { - beforeEach(() => { - chooseSemester('Syksy 2017', 'from') - chooseSemester('Kevät 2024', 'to') - }) - - it('Initial view is correct', () => { - cy.contains('All courses total') - cy.contains('Academic and Professional') - cy.contains('AYKK-RUKIRJ') - }) - - it('Faculties tab shows numbers', () => { - cy.get('table > tbody > tr:first').within(() => { - cy.get('td').should('have.length', 15) - cy.get('td').eq(0).contains('All courses total') - const numbers = [2076, 36, 9, 34, 759, 15, 40, 6, 51, 1, 24, 1059, 42, 0] - numbers.forEach((number, index) => { - cy.get('td') - .eq(index + 1) - .contains(number) - }) - }) - }) - - it('Faculties tab "exceeding" button works', () => { - cy.cs('difference-button').click() - checkNumbers([66, 3, 0, 4, 18, 0, 1, 1, 4, 0, 0, 31, 3, 1], 15, 'faculties') - }) - - it('Faculties tab semester selector changes numbers', () => { - chooseSemester('Syksy 2020', 'from') - checkNumbers([1184, 28, 6, 28, 499, 4, 10, 2, 36, 0, 9, 535, 27, 0], 15, 'faculties') - }) - }) - - describe('Semester tab', () => { - beforeEach(() => { - cy.contains('By semesters').click() - chooseSemester('Syksy 2017', 'from') - chooseSemester('Kevät 2024', 'to') - }) - - it('Semester tab shows numbers', () => { - checkNumbers([2076, 69, 26, 298, 58, 343, 98, 438, 138, 310, 90, 123, 74, 10, 1], 16, 'semesters') - }) - }) - }) - - describe('with a user with no rights', () => { - it('"Access denied" is shown', () => { - cy.init('/languagecenterview', 'norights') - cy.contains('Access denied') - cy.contains("You don't currently have permission to view this page.") - cy.contains('Special populations').click() - cy.contains('Language center view').should('not.exist') - }) - }) -}) diff --git a/cypress/e2e/Population_statistics.js b/cypress/e2e/Population_statistics.js deleted file mode 100644 index c92d9fad2..000000000 --- a/cypress/e2e/Population_statistics.js +++ /dev/null @@ -1,443 +0,0 @@ -/// -// Now "Class statistics" in UI - -const selectStudyProgramme = programme => { - cy.cs('population-programme-selector').within(() => - cy.get('input').should('have.attr', 'placeholder', 'Select degree programme') - ) - cy.cs('population-programme-selector-parent').click() - cy.cs('population-programme-selector-parent').within(() => cy.contains(programme).click()) -} - -const selectStudyTrack = studyTrack => { - cy.cs('population-studytrack-selector').within(() => - cy.get('input').should('have.attr', 'placeholder', 'Select study track') - ) - cy.cs('population-studytrack-selector-parent').click() - cy.cs('population-studytrack-selector-parent').within(() => cy.contains(studyTrack).click()) -} - -describe('Population statistics tests', () => { - const getPath = programme => { - return `/populations?months=49&semesters=FALL&semesters=SPRING&programme=${programme}&years=2020` - } - const pathToMathBSc2020 = getPath('KH50_001') - const pathToMathMSc2020 = getPath('MH50_001') - - describe('When using basic user', () => { - beforeEach(() => { - cy.init('/populations') - cy.intercept('/api/populationstatistics/studyprogrammes').as('studyprogrammes') - cy.intercept('/api/studyprogrammes/**/studytracks').as('studytracks') - }) - - describe('Population search', () => { - it('Info box works', () => { - cy.cs('PopulationSearch-info-box-content').should('not.exist') - cy.cs('PopulationSearch-info-box-button').hover() - cy.cs('PopulationSearch-info-box-content').should('be.visible') - cy.cs('PopulationSearch-info-box-content').contains('Tässä osiossa voi tarkastella') - cy.cs('PopulationSearch-info-box-button').trigger('mouseout') - cy.cs('PopulationSearch-info-box-content').should('not.exist') - }) - - // TODO: Delete MUI - it.skip('Form is usable', { retries: { runMode: 2 } }, () => { - cy.contains('Search for class') - cy.contains('See class').should('be.disabled') - - cy.cs('population-year-selector').as('yearSelect') - cy.cs('population-year-decrement').as('yearDecrement') - cy.cs('population-year-increment').as('yearIncrement') - - cy.get('@yearSelect').click() - cy.contains('2018 - 2019').click() - cy.get('@yearSelect').within(() => cy.contains('2018 - 2019')) - cy.get('@yearDecrement').click() - cy.get('@yearSelect').within(() => cy.contains('2017 - 2018')) - cy.get('@yearIncrement').click() - cy.get('@yearSelect').within(() => cy.contains('2018 - 2019')) - - cy.cs('population-studytrack-selector').within(() => { - cy.get('input').should('have.attr', 'placeholder', 'No study tracks available') - }) - selectStudyProgramme('Matematiikan ja tilastotieteen maisteriohjelma') - cy.contains('See class').should('be.enabled') - selectStudyTrack('Matematiikka ja soveltava matematiikka') - cy.contains('See class').should('be.enabled') - }) - - describe('Correct population is shown for programme', () => { - // TODO: Delete MUI - it.skip('without study tracks', () => { - cy.wait('@studyprogrammes').its('response.statusCode').should('be.oneOf', [200, 304]) - selectStudyProgramme('Matemaattisten tieteiden kandiohjelma') - cy.wait('@studytracks').its('response.statusCode').should('be.oneOf', [200, 304]) - cy.contains('See class').click() - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Class of 2017 - 2018, 47 students') - }) - - // TODO: Delete MUI - it.skip('with study tracks', () => { - selectStudyProgramme('Matematiikan ja tilastotieteen maisteriohjelma') - cy.wait('@studytracks').its('response.statusCode').should('be.oneOf', [200, 304]) - selectStudyTrack('Matematiikka ja soveltava matematiikka') - cy.contains('See class').click() - cy.contains('Matematiikan ja tilastotieteen maisteriohjelma 2017 - 2018') - cy.contains('studytrack MAST-MSM') - cy.contains('Class size 1 students') - }) - }) - }) - - it('Population statistics is usable on general level', () => { - cy.visit(pathToMathBSc2020) - cy.cs('filtered-students') - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Class of 2020 - 2021, 30 students') - cy.contains('Excludes exchange students') - cy.contains('Excludes students with non-degree study right') - cy.contains('Excludes students who have transferred out of this programme') - cy.cs('filtered-students') - }) - - // This test sometimes fails on headless mode. It seems that the click on the - // 'Fetch class with new settings' button doesn't always trigger history.push() - // so the page doesn't reload. This is why waiting also doesn't help. - it('Advanced settings work', { retries: 2 }, () => { - cy.visit(pathToMathMSc2020) - cy.get('[data-cy=advanced-toggle]').click() - // only spring - cy.cs('toggle-fall').click() - cy.contains('Fetch class').click() - cy.contains('Credit accumulation (for 17 students)') - cy.url().should('not.include', 'semesters=FALL') - // only fall - cy.get('[data-cy=advanced-toggle]').click() - cy.cs('toggle-fall').click() - cy.cs('toggle-spring').click() - cy.contains('Fetch class').click() - cy.contains('Credit accumulation (for 9 students)') - cy.url().should('not.include', 'semesters=SPRING') - // spring + fall - cy.get('[data-cy=advanced-toggle]').click() - cy.cs('toggle-spring').click() - cy.contains('Fetch class').click() - cy.contains('Credit accumulation (for 26 students)') - cy.url().should('include', 'semesters=FALL&semesters=SPRING') - }) - - describe('Credit statistics', () => { - it("'Credits gained' tab shows correct statistics for all students of the class and also students grouped by admission type", () => { - cy.clock(new Date('2024-08-30').getTime(), ['Date']) - cy.visit(pathToMathBSc2020) - const totalStudents = 27 - cy.contains('Credit statistics') - .parent() - .then($parentDiv => { - if (!$parentDiv.hasClass('active')) cy.contains('Credit statistics').click() - }) - cy.contains('Credits gained').click() - const limits = [1, 45, 90, 135, 180, null] - const ranges = limits.map((limit, i) => (i === 0 ? [null, 0] : [limits[i - 1], limit])).reverse() - - const getTableData = (selector, numbersOfStudents) => { - const studentsInCategory = numbersOfStudents.reduce((acc, val) => acc + val, 0) - return ranges.map((range, index) => ({ - selector: `[data-cy='credits-gained-table-${selector}']`, - start: range[0], - end: range[1], - students: numbersOfStudents[index], - percentage: `${((numbersOfStudents[index] / studentsInCategory) * 100).toFixed(1)}%`, - })) - } - - cy.cs('credits-gained-table-All students of the class').within(() => { - cy.get('th').eq(1).contains('Credits gained between 01.08.2020 and 30.08.2024') - cy.get('th').eq(1).contains('(49 months)') - cy.get('th').eq(2).contains('Number of students') - cy.get('th').eq(2).contains(`(n = ${totalStudents})`) - cy.get('th').eq(3).contains('Percentage of population') - }) - - for (const category of [ - getTableData('All students of the class', [9, 5, 7, 4, 2, 0]), - getTableData('Avoin väylä', [0, 1, 3, 2, 0, 0]), - getTableData('Muu', [0, 1, 1, 1, 0, 0]), - getTableData('Todistusvalinta', [9, 3, 3, 1, 2, 0]), - ]) { - category.forEach(({ selector, start, end, students, percentage }, index) => { - let value - if (start === null) { - value = '0' - } else if (end === null) { - value = `${start} ≤ credits` - } else { - value = `${start} ≤ credits < ${end}` - } - cy.get(`${selector} [data-cy='credits-gained-table-body']`).within(() => { - cy.get('tr') - .eq(index) - .within(() => { - cy.get('td').eq(1).contains(value) - cy.get('td').eq(2).contains(students) - cy.get('td').eq(3).contains(percentage) - }) - }) - }) - } - - cy.get( - "[data-cy='credits-gained-table-All students of the class'] [data-cy='credits-gained-table-body'] td:nth-child(3)" - ).then(tds => { - const sum = [...tds].reduce((acc, td) => acc + parseInt(td.innerText, 10), 0) - expect(sum).to.equal(totalStudents) - }) - }) - - it("'Statistics' tab shows correct statistics for all students of the class and also students grouped by admission type", () => { - cy.visit(pathToMathBSc2020) - cy.contains('Credit statistics') - .parent() - .then($parentDiv => { - if (!$parentDiv.hasClass('active')) cy.contains('Credit statistics').click() - }) - cy.cs('credit-statistics-tab').click() - const rows = ['Total credits', 'Average', 'Median', 'Standard deviation', 'Minimum', 'Maximum'] - const categories = [ - { - selector: 'All students of the population', - data: ['6136.50', '227.28', '197.00', '117.94', '60', '533'], - size: 27, - }, - { - selector: 'Muu', - data: ['580.00', '193.33', '192.00', '36.75', '149', '239'], - size: 3, - }, - { - selector: 'Todistusvalinta', - data: ['3657.50', '203.19', '193.50', '98.35', '60', '460'], - size: 18, - }, - { - selector: 'Avoin väylä', - data: ['1899.00', '316.50', '257.00', '150.43', '150', '533'], - size: 6, - }, - ] - - for (const { selector, data, size } of categories) { - cy.get(`[data-cy='statistics-table-${selector}']`).within(() => { - cy.contains('h5', selector) - cy.contains("[data-cy='credit-stats-population-size']", `n = ${size}`) - cy.get('table tbody').within(() => { - rows.forEach((text, index) => { - cy.get('tr') - .eq(index) - .within(() => { - cy.get('td').eq(0).contains(text) - cy.get('td').eq(1).contains(data[index]) - }) - }) - }) - }) - } - }) - }) - - describe('Courses of class', () => { - it('Is displayed and link to individual course stats page works', () => { - cy.visit(pathToMathBSc2020) - cy.contains('Courses of class').click() - cy.intercept('/api/courseyearlystats**').as('coursePage') - cy.cs('toggle-group-module-MAT110').click() - cy.contains('td', 'MAT11001').siblings().find('[data-testid="NorthEastIcon"]').click() - cy.wait('@coursePage') - cy.url().should('include', '/coursestatistics') - cy.contains('MAT11001') // Johdatus yliopistomatematiikkaan - cy.contains('AYMAT11001') // Avoin yo: Johdatus yliopistomatematiikkaan - cy.contains('57033') // Johdatus yliopistomatematiikkaan - cy.contains('A57033') // Avoin yo: Johdatus yliopistomatematiikkaan - }) - - it('Curriculum selection works', () => { - cy.visit(pathToMathBSc2020) - cy.contains('Courses of class').click() - cy.get('[data-cy=curriculum-picker]').contains('2020–2023') - cy.get('[data-cy=toggle-group-module-MAT-tyo]') - cy.get('[data-cy=curriculum-picker]').click() - cy.contains('2023–2026').click() - cy.get('[data-cy=toggle-group-module-MAT-tyo]').should('not.exist') - }) - - it('Courses data is changed when curriculum is changed', () => { - cy.visit(pathToMathBSc2020) - cy.contains('Courses of class').click() - - cy.cs('curriculum-picker').scrollIntoView() - cy.cs('curriculum-picker').should('be.visible') - cy.cs('curriculum-picker').click() - cy.contains('2020–2023').click({ force: true }) - cy.contains('Students (27)') - cy.cs('toggle-group-module-DIGI-k').should('exist') - cy.cs('toggle-group-module-DIGI-k').scrollIntoView() - cy.cs('toggle-group-module-DIGI-k').should('be.visible') - cy.cs('toggle-group-module-DIGI-k').click({ force: true }) - cy.contains('DIGI-100').should('exist') - - cy.cs('curriculum-picker').scrollIntoView() - cy.cs('toggle-group-module-DIGI-k').should('be.visible') - cy.cs('curriculum-picker').click() - cy.contains('2023–2026').click({ force: true }) - cy.cs('toggle-group-module-DIGI-k').should('exist') - cy.contains('DIGI-100').should('not.exist') - }) - - it('Courses data is changed when filtered students change', () => { - cy.visit(pathToMathBSc2020) - - cy.cs('graduatedFromProgrammeFilter-filter-card').within(() => { - cy.cs('graduatedFromProgrammeFilter-header').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="1"]').click() - cy.get('input[name="graduatedFromProgrammeFilter"][value="1"]').should('be.checked') - }) - - cy.contains('Students (16)') - }) - }) - - describe('Students', () => { - beforeEach(() => { - cy.visit(pathToMathBSc2020) - cy.contains('Students (27)') - .parent() - .then($parentDiv => { - if (!$parentDiv.hasClass('active')) cy.contains('Students (27)').click() - }) - }) - - it("'General tab' is usable", () => { - cy.cs('ooditable-general').within(() => { - cy.contains('522142') - cy.contains('Tilastotiede') - cy.contains('Matematiikka') - cy.contains('Taloustieteen maisteriohjelma') - cy.contains('Todistusvalinta') - cy.contains('Saksa') - cy.contains('Female') - }) - }) - - it("'Courses tab' is usable", () => { - cy.cs('student-table-tabs').within(() => { - cy.contains('Courses').click() - }) - cy.cs('ooditable-courses').within(() => { - cy.contains('MAT12001') - cy.contains('MAT21001') - }) - }) - - it("'Modules tab' Displays correct modules based on the selected programme", () => { - cy.cs('student-table-tabs').contains('Modules').click() - cy.cs('ooditable-modules').within(() => { - cy.contains('MAT011') - cy.contains('MAT110') - }) - cy.contains('Courses of class').click() - cy.cs('curriculum-picker').click() - cy.contains('2023–2026').click() - cy.contains('Courses of class').click() - cy.cs('ooditable-modules').within(() => { - cy.contains('MAT011').should('not.exist') - cy.contains('MAT110') - }) - }) - - it("Empty 'tags' tab has a link to the page where tags can be created", () => { - cy.cs('student-table-tabs').within(() => { - cy.contains('Tags').click() - }) - cy.contains('No tags defined. You can define them here.').find('a').click() - cy.url().should('include', '/study-programme/KH50_001?tab=4') - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Create new tag') - cy.cs('create-button').should('be.disabled') - }) - }) - }) - - describe('When using admin', () => { - it('Student list checking works as intended', () => { - cy.init(pathToMathBSc2020, 'admin') - const existing = '433237' - const nonExisting = '550004' - cy.contains('Students (27)') - .parent() - .then($parentDiv => { - if (!$parentDiv.hasClass('active')) cy.contains('Students (27)').click() - }) - cy.contains(existing) - cy.contains(nonExisting).should('not.exist') - cy.contains('button', 'Check student numbers').click() - cy.contains('Check for student numbers') - cy.cs('check-student-numbers').type(`${existing}{enter}${nonExisting}`) - cy.contains('button', 'Check students').click() - cy.get('#checkstudentsresults').within(() => { - cy.cs('found-title').click() - cy.cs('found-data').contains(existing) - cy.cs('not-found-title').click() - cy.cs('not-found-data').contains(nonExisting) - cy.cs('not-searched-title').click() - cy.cs('not-searched-data').contains('457144') - }) - cy.contains('button', 'Close').click() - cy.contains('Student numbers in list and in Sisu').should('not.exist') - }) - }) - - describe('When using IAM user', () => { - beforeEach(() => { - cy.init(pathToMathBSc2020, 'onlyiamrights') - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Class of 2020 - 2021, 30 students') - }) - - it('Population statistics is visible', () => { - cy.cs('PopulationQueryCard').within(() => { - cy.contains('Excludes exchange students') - cy.contains('Excludes students with non-degree study right') - cy.contains('Excludes students who have transferred out of this programme') - }) - }) - - it('Only correct panels are visible', () => { - cy.cs('panelview-parent').within(() => { - cy.cs('Credit accumulation (for 27 students)') - cy.cs('Credit statistics') - cy.cs('Age distribution') - cy.cs('Courses of class') - }) - }) - - it('Ages cannot be ungrouped', () => { - cy.contains('Age distribution') - .parent() - .then($parentDiv => { - if (!$parentDiv.hasClass('active')) cy.contains('Age distribution').click() - }) - cy.contains('ui.checked.toggle.checkbox', 'Group ages').should('not.exist') - }) - - it('Age filter is not visible', () => { - cy.get("[data-cy='filtered-students']") - cy.get("[data-cy='Age-filter-card']").should('not.exist') - }) - - it('Students tab is not available', () => { - cy.contains('Students (27)').should('not.exist') - }) - }) -}) diff --git a/cypress/e2e/Routes.js b/cypress/e2e/Routes.js deleted file mode 100644 index e1aaa05e3..000000000 --- a/cypress/e2e/Routes.js +++ /dev/null @@ -1,85 +0,0 @@ -import { userHeaders } from '../support/commands.js' - -const getBaseRoutes = [ - ['/', {}], - ['/changelog', {}], - ['/completedcoursessearch', {}], - ['/university', {}], - ['/feedback', {}], - ['/populations', { roles: ['fullSisuAccess'], programmeRights: [] }], - ['/study-programme', { roles: ['fullSisuAccess'], programmeRights: [] }], - ['/study-programme/KH50_001', { roles: ['fullSisuAccess'], programmeRights: ['KH50_001'] }], - ['/coursepopulation', { roles: ['fullSisuAccess'], programmeRights: [] }], - ['/users', { roles: ['admin'] }], - ['/users/334', { roles: ['admin'] }], - ['/updater', { roles: ['admin'] }], - ['/coursestatistics', { roles: ['fullSisuAccess', 'courseStatistics'], programmeRights: [] }], - ['/faculties', { roles: ['fullSisuAccess', 'facultyStatistics'] }], - ['/faculties/hy-org-1000000911', { roles: ['fullSisuAccess', 'facultyStatistics'] }], - ['/students', { roles: ['fullSisuAccess', 'studyGuidanceGroups'], programmeRights: [] }], - ['/students/545400', { roles: ['fullSisuAccess', 'studyGuidanceGroups'], programmeRights: [] }], - ['/custompopulation', { roles: ['fullSisuAccess', 'studyGuidanceGroups'], programmeRights: [] }], - ['/teachers', { roles: ['teachers'] }], - ['/teachers/hy-hlo-1463447', { roles: ['teachers'] }], - ['/studyguidancegroups', { roles: ['studyGuidanceGroups'] }], - ['/studyguidancegroups/otm-b3b52ff5-88f6-4d52-bd18-0588023b6322', { userId: '', roles: ['studyGuidanceGroups'] }], - ['/close-to-graduation', { roles: ['fullSisuAccess', 'studyGuidanceGroups'] }], - ['/languagecenterview', { iamGroups: ['grp-kielikeskus-esihenkilot'] }], -] - -for (const user of userHeaders) { - if (user.uid === 'admin') continue - describe(`${user.displayname} has access only to views that were intended`, () => { - let userInfo - before(() => { - cy.request({ method: 'GET', url: '/api/login', headers: user }).then(({ body }) => (userInfo = body?.user)) - }) - - beforeEach(() => cy.wrap(userInfo).should('not.be.undefined')) - beforeEach(() => { - cy.intercept('**/api/**', req => { - req.on('response', res => { - expect(res.statusCode, `${req.method} ${req.url}`).to.be.lessThan(500) - }) - }) - }) - - for (const [route, requirements] of getBaseRoutes) { - it(`Checking access ${route}`, () => { - cy.init(route, user.uid) - - const requiredUserId = !requirements.userId || requirements.userId === userInfo.userId - - const requiredRoles = !requirements.roles || requirements.roles?.some(role => userInfo.roles?.includes(role)) - - const requiredRights = - !requirements.requireProgrammeRights || - userInfo.roles?.includes('fullSisuAccess') || - requirements.programmeRights.every(role => userInfo.programmeRights?.includes(role)) - - // This is defined in frontend ProtectedRoute component. - const specialNeedsRoutes = [ - 'populations', - 'study-programme', - 'coursepopulation', - 'coursestatistics', - 'students', - 'custompopulation', - ] - - const mankeli = specialNeedsRoutes.some(path => route.includes(path)) - ? requiredRoles || requiredRights - : requiredRoles && requiredRights - - const shouldHaveAccess = mankeli && requiredUserId - - if (shouldHaveAccess) { - cy.contains('Something broke').should('not.exist') - cy.contains('Access denied').should('not.exist') - } else { - cy.contains('Access denied') - } - }) - } - }) -} diff --git a/cypress/e2e/Students.js b/cypress/e2e/Students.js deleted file mode 100644 index 01e8202e3..000000000 --- a/cypress/e2e/Students.js +++ /dev/null @@ -1,294 +0,0 @@ -/// - -const student = { - firstNames: 'Varpu Roope', - lastName: 'Mårtensson', - studentNumber: '550003', - sisPersonId: 'hy-hlo-115926826', - email: 'sisutestidata134902@testisisudata.fi', -} - -const typeToSearch = text => { - cy.cs('student-search').type(text) -} - -const typeStudentNumberAndClick = studentNumber => { - typeToSearch(studentNumber) - cy.contains('td', studentNumber).click() -} - -describe('Students tests', () => { - describe('When using basic user', () => { - beforeEach(() => { - cy.init('') - cy.contains('Students').click() - cy.url().should('include', '/students') - cy.contains('Show student names') - }) - - // FIXME: Flaky - it('Students search form is usable', () => { - typeToSearch(student.lastName) - cy.contains('Student number') - cy.contains('Last name').should('not.exist') - cy.contains('First names').should('not.exist') - cy.contains('Started') - cy.contains('Credits') - cy.contains('Active study rights') - cy.contains(student.firstNames).should('not.exist') - cy.contains(student.lastName).should('not.exist') - - cy.cs('toggleStudentNames').click() - cy.contains(student.firstNames) - cy.contains('Student number') - cy.contains('Last name') - cy.contains('First names') - cy.contains('Started') - cy.contains('Credits') - cy.contains('Active study rights') - cy.contains(student.firstNames) - cy.contains(student.lastName) - - cy.cs('toggleStudentNames').click() - cy.contains('Student number') - cy.contains('Last name').should('not.exist') - cy.contains('First names').should('not.exist') - cy.contains('Started') - cy.contains('Credits') - cy.contains('Active study rights') - cy.contains(student.firstNames).should('not.exist') - cy.contains(student.lastName).should('not.exist') - }) - - it('Search term must be at least 4 characters long', () => { - typeToSearch(student.lastName.slice(0, 3)) - cy.contains('Search term is not accurate enough') - typeToSearch(student.lastName.slice(3)) - cy.get('table tbody tr').should('have.length', 1) - }) - - it('Can search with student number too', () => { - typeToSearch(student.studentNumber) - cy.contains(student.studentNumber) - }) - - it('Can get student specific page by clicking student', () => { - typeStudentNumberAndClick(student.studentNumber) - cy.contains('Matemaattisten tieteiden kandiohjelma (01.08.2020–31.07.2027)') - cy.contains(student.lastName).should('not.exist') - cy.contains(student.firstNames).should('not.exist') - cy.contains(student.email).should('not.exist') - - cy.cs('toggleStudentNames').click() - cy.contains(student.lastName) - cy.contains(student.firstNames) - cy.contains(student.email) - - cy.cs('toggleStudentNames').click() - cy.contains(student.lastName).should('not.exist') - cy.contains(student.firstNames).should('not.exist') - cy.contains(student.email).should('not.exist') - }) - - it("'Update student' button is not shown", () => { - typeStudentNumberAndClick(student.studentNumber) - cy.cs('student-info-card').within(() => { - cy.contains('button', 'Update student').should('not.exist') - }) - }) - - it('Can get back to search menu', () => { - typeStudentNumberAndClick(student.studentNumber) - cy.go('back') - cy.contains('Student number').should('not.exist') - cy.contains('Credits').should('not.exist') - }) - - it('Can jump to course', () => { - typeStudentNumberAndClick(student.studentNumber) - cy.contains('Tilastollinen päättely I (MAT12004)') - .parent() - .siblings() - .last() - .within(() => { - cy.get('a').click() - }) - cy.url().should('include', '/coursestatistics') - cy.contains('MAT12004') // Tilastollinen päättely I - cy.contains('AYMAT12004') // Avoin yo: Tilastollinen päättely I - cy.contains('57046') // Johdatus tilastolliseen päättelyyn - }) - - it('Has correct Sisu link', () => { - typeStudentNumberAndClick(student.studentNumber) - cy.cs('sisu-link') - .should('have.attr', 'href') - .and('include', `https://sisu.helsinki.fi/tutor/role/staff/student/${student.sisPersonId}/basic/basic-info`) - }) - - it('Semester enrollments can be toggled', () => { - typeStudentNumberAndClick(student.studentNumber) - const programmes = [ - 'Oikeustieteen tohtoriohjelma', - 'Matemaattisten tieteiden kandiohjelma', - 'Oikeustieteen maisterin koulutusohjelmaOikeusnotaarin koulutusohjelma', - ] - cy.cs('student-info-card').within(() => { - cy.contains('Enrollments').click() - cy.get('table tbody tr') - .should('have.length', 3) - .each(($tr, index) => { - cy.wrap($tr).within(() => { - cy.get('td').eq(0).should('have.text', programmes[index]) - }) - }) - }) - }) - - it("Searching with bad name doesn't yield results", () => { - typeToSearch('SWAG LITTINEN') - cy.contains('Student number').should('not.exist') - }) - - it("Searching with bad student number doesn't yield results", () => { - typeToSearch('01114') - cy.contains('Student number').should('not.exist') - }) - - it('Can jump to population page', () => { - typeStudentNumberAndClick(student.studentNumber) - cy.cs('study-rights-section').within(() => { - cy.contains('Matemaattisten tieteiden kandiohjelma') - .parent() - .within(() => cy.get('a').click()) - }) - cy.contains('Matemaattisten tieteiden kandiohjelma') - cy.contains('Class of 2020 - 2021, 30 students') - }) - - it('Grade graph works in all three different modes', () => { - typeStudentNumberAndClick(student.studentNumber) - cy.contains('button', 'Grade graph').click() - cy.contains('button', 'Show group mean').click() - cy.cs('group-size-input').within(() => { - cy.contains('label', 'Group size') - cy.get('input').should('have.value', '5') - }) - cy.cs('group-size-input').within(() => { - cy.contains('label', 'Group size') - cy.get('input').clear() - cy.get('input').type('10') - cy.get('input').should('have.value', '10') - }) - cy.contains('button', 'Show semester mean').click() - }) - - describe('Bachelor Honours section', () => { - it("Shows 'Qualified for Honours' tag and main modules info when the student is qualified", () => { - cy.visit('/students/495976') - cy.contains('h2', 'Bachelor Honours') - cy.contains('[data-cy=honours-chip-qualified]', 'Qualified for Honours') - cy.contains('Study modules').click() - cy.get('[data-cy=main-modules] tbody tr') - .should('have.length', 3) - .each(($tr, index) => { - const info = [ - ['07.05.2020', 'Matemaattisten tieteiden kandiohjelma (KH50_001)', 'Hyv.'], - ['08.05.2018', 'Matematiikka, perusopinnot (MAT110)', '4'], - ['25.02.2020', 'Matematiikka, aineopinnot (MAT210)', '4'], - ] - cy.wrap($tr).within(() => { - info[index].forEach((text, i) => { - cy.get('td').eq(i).contains(text) - }) - }) - }) - }) - - it("Shows 'Did not graduate in time' when the student has graduated but not in time", () => { - cy.visit('/students/540355') - cy.contains('h2', 'Bachelor Honours') - cy.contains('[data-cy=honours-chip-not-qualified]', 'Not qualified for Honours') - cy.contains('[data-cy=honours-chip-error]', 'Did not graduate in time') - }) - - it("Shows 'Module grades too low' when the student has graduated in time but has too low grades", () => { - cy.visit('/students/547934') - cy.contains('h2', 'Bachelor Honours') - cy.contains('[data-cy=honours-chip-not-qualified]', 'Not qualified for Honours') - cy.contains('[data-cy=honours-chip-error]', 'Module grades too low') - }) - - it("Shows 'Might need further inspection' when the student has graduated in time but has more than four main modules", () => { - cy.visit('/students/478837') - cy.contains('h2', 'Bachelor Honours') - cy.contains('[data-cy=honours-chip-inspection]', 'Might need further inspection') - }) - - it("Shows 'Has not graduated' when the student has not graduated", () => { - cy.visit(`students/${student.studentNumber}`) - cy.contains('h2', 'Bachelor Honours') - cy.contains('[data-cy=honours-chip-not-qualified]', 'Not qualified for Honours') - cy.contains('[data-cy=honours-chip-error]', 'Has not graduated') - }) - }) - }) - - // Use admin to see all students - describe('When using admin user', () => { - beforeEach(() => { - cy.init('/students', 'admin') - }) - - it('Does not crash if student has no study rights or courses', () => { - typeStudentNumberAndClick('450730') - cy.contains('Credits: 0') - }) - - it("'Update student' button is shown", () => { - typeStudentNumberAndClick(student.studentNumber) - cy.cs('student-info-card').within(() => { - cy.contains('button', 'Update student') - }) - }) - - it('Bachelor Honours section is not shown for students outside of Faculty of Science', () => { - cy.visit('/students/453146') - cy.contains('h2', 'Bachelor Honours').should('not.exist') - }) - - it('When a study plan is selected, courses included in the study plan are highlighted with a blue background', () => { - cy.visit('/students/550789') - cy.contains('Study rights') - cy.get('[data-cy=KH40_005-0]').contains('Kulttuurien tutkimuksen kandiohjelma') - cy.get('[data-cy=KH40_005-0]').within(() => { - cy.get('td').eq(1).click() - }) - cy.contains('table tbody tr', 'Kandidaatintutkielma (KUKA-LIS222)').should( - 'have.css', - 'background-color', - 'rgb(232, 244, 255)' - ) - }) - - it("If there's a study plan corresponding to the degree programme, completed credits are displayed", () => { - cy.visit('/students/550789') - cy.contains('Study rights') - cy.get('[data-cy=KH40_005-0]').contains('Kulttuurien tutkimuksen kandiohjelma') - cy.get('[data-cy=KH40_005-0]').within(() => { - cy.get('td') - .eq(4) - .contains(/^185 cr$/) - }) - }) - - it("If there's a study plan corresponding to the degree programme and the student hasn't graduated, percentage of completion is also displayed", () => { - cy.visit('/students/458723') - cy.contains('Study rights') - cy.get('[data-cy=KH20_001-0]').contains('Oikeusnotaarin koulutusohjelma') - cy.get('[data-cy=KH20_001-0]').within(() => { - cy.get('td').eq(4).contains('69% (125 cr)') - }) - }) - }) -}) diff --git a/cypress/e2e/Study_guidance_groups.js b/cypress/e2e/Study_guidance_groups.js deleted file mode 100644 index 2175e6000..000000000 --- a/cypress/e2e/Study_guidance_groups.js +++ /dev/null @@ -1,164 +0,0 @@ -/// - -describe('Study guidance group tests', () => { - describe('Study guidance group overview page', () => { - describe('without study guidance groups', () => { - it('shows the correct notification', () => { - cy.init('/studyguidancegroups', 'admin') - cy.contains('Study guidance groups') - cy.contains('You do not have access to any study guidance groups.') - }) - }) - - describe('without correct rights', () => { - it('shows the correct notification', () => { - cy.init('/studyguidancegroups') - cy.contains('Access denied') - cy.contains( - "You don't currently have permission to view this page. If you believe this is a mistake, please contact oodikone@helsinki.fi." - ) - }) - }) - - describe('with study guidance groups', () => { - beforeEach(() => { - cy.init('/studyguidancegroups', 'onlystudyguidancegroups') - cy.intercept('/api/studyguidancegroups', { fixture: 'studyGuidanceGroups.json' }) - }) - - it('shows the correct data', () => { - cy.contains('Study guidance groups') - - const studyGuidanceGroupsTableContent = [ - ['MAT kandit 2020', 3, 'Matemaattisten tieteiden kandiohjelma', '2020 - 2021'], - ['Oma ohjausryhmä', 2, 'Add degree programme', 'Add starting year'], - ] - - cy.checkTableStats(studyGuidanceGroupsTableContent, 'study-guidance-group-overview') - }) - - it('has working links to single study guidance groups', () => { - cy.cs('study-guidance-group-link-sgg-cypress-1').click() - cy.url().should('eq', `${Cypress.config().baseUrl}/studyguidancegroups/sgg-cypress-1`) - }) - }) - }) - - describe('Page for single study guidance group', () => { - beforeEach(() => { - cy.intercept('/api/studyguidancegroups', { fixture: 'studyGuidanceGroups.json' }) - }) - - it('has a working back button', () => { - cy.init('/studyguidancegroups/sgg-cypress-1', 'onlystudyguidancegroups') - - cy.get('button').contains('Back to groups').click() - cy.url().should('eq', `${Cypress.config().baseUrl}/studyguidancegroups`) - }) - - describe('without associated degree programme and year', () => { - beforeEach(() => { - cy.init('/studyguidancegroups/sgg-cypress-2', 'onlystudyguidancegroups') - }) - - it('shows the correct panes', () => { - cy.contains('Oma ohjausryhmä') - cy.cs('Credit accumulation (for 2 students)') - cy.cs('Age distribution') - cy.cs('Courses of population') - cy.contains('Students (2)') - cy.cs('Credit statistics').should('not.exist') - }) - - it.skip('students table has the correct tabs', () => { - cy.contains('Students (2)').click() - cy.get('[data-cy="student-table-tabs"] .ui.attached.tabular.menu').then($menu => { - const tabNames = Array.from($menu[0].children).map(elem => elem.innerText) - expect(tabNames).to.deep.equal(['General']) - }) - }) - - it.skip('general tab of the students table has the correct columns', () => { - const colHeaders = [ - 'Student number', - 'All credits', - 'Credits since 1.1.1970', - 'Start year at uni', - 'Degree programmes', - 'Tags', - ] - cy.contains('Students (2)').click() - cy.get('[data-cy="student-table-tabs"] table thead tr').within(() => { - colHeaders.every(heading => cy.contains(heading)) - }) - }) - }) - - describe('with associated degree programme and year', () => { - beforeEach(() => { - cy.init('/studyguidancegroups/sgg-cypress-1', 'onlystudyguidancegroups') - }) - - it('shows the correct labels', () => { - cy.get('h4').contains('MAT kandit 2020') - cy.get('.MuiChip-root:first').contains('Matemaattisten tieteiden kandiohjelma') - cy.get('.MuiChip-root:last').contains('2020 - 2021') - }) - - it('shows the correct panes', () => { - cy.cs('Credit accumulation (for 3 students)') - cy.cs('Credit statistics') - cy.cs('Age distribution') - cy.cs('Courses of population') - cy.contains('Students (3)') - }) - - it("clicking the 'Show credits starting from the associated academic year' filter", () => { - cy.get('[data-cy="ParticipationDate-filter-card"][data-active="false"]') - cy.cs('Credit accumulation (for 3 students)').click() - cy.get('label').contains('Show credits starting from the associated academic year').click() - cy.get('[data-cy="ParticipationDate-filter-card"][data-active="true"]') - cy.get('.date-picker') - .eq(0) - .within(() => cy.get('input').should('have.value', '01.08.2020')) - cy.contains('Reset All Filters') - cy.get('label').contains('Show credits starting from the associated academic year').click() - cy.get('[data-cy="ParticipationDate-filter-card"][data-active="false"]') - }) - - it.skip('students table has the correct tabs', () => { - cy.contains('Students (3)').click() - cy.get('[data-cy="student-table-tabs"] .ui.attached.tabular.menu').then($menu => { - const tabNames = Array.from($menu[0].children).map(elem => elem.innerText) - expect(tabNames).to.deep.equal(['General', 'Courses', 'Modules', 'Progress']) - }) - }) - - it.skip('general tab of the students table has the correct columns', () => { - const colHeaders = [ - 'Student number', - 'All credits', - 'Credits in HOPS', - 'Credits since 1.8.2020', - 'Start of study right', - 'Started in programme', - 'Semesters present', - 'Graduation date', - 'Start year at uni', - 'Other programmes', - 'Transferred from', - 'Admission type', - 'Gender', - 'Citizenships', - 'Curriculum period', - 'Latest attainment date', - 'Tags', - ] - cy.contains('Students (3)').click() - cy.get('[data-cy="student-table-tabs"] table thead tr').within(() => { - colHeaders.every(heading => cy.contains(heading)) - }) - }) - }) - }) -}) diff --git a/cypress/e2e/Teachers.js b/cypress/e2e/Teachers.js deleted file mode 100644 index 72e1c2b91..000000000 --- a/cypress/e2e/Teachers.js +++ /dev/null @@ -1,64 +0,0 @@ -/// - -describe('Teachers page tests', () => { - beforeEach(() => { - // login as admin = has teacher rights - cy.init('/teachers', 'admin') - cy.url().should('include', '/teachers') - }) - - const teacher1 = 'Luokkanen Liisa Viljami' - const teacher2 = 'Perälä Juhani Susanna' - - const statisticsHeaders = ['Name', 'Credits', 'Credits transferred', 'Passed'] - - it('Check Statistics', () => { - cy.cs('semester-start').click() - cy.contains('Syksy 2020').click() - cy.cs('course-providers').click() - cy.contains('Matemaattisten tieteiden kandiohjelma').click() - cy.get('body').click(0, 0) // Click outside of the select - cy.cs('search-statistics').click() - - cy.contains('Teacher') - cy.get('table thead tr th').should('have.length', 4) - statisticsHeaders.forEach((header, index) => { - cy.get('table thead tr th').eq(index).should('contain', header) - }) - cy.contains('td', teacher1).siblings().eq(0).contains('235') - cy.contains('td', teacher1).siblings().eq(2).contains('97.40%') - cy.contains('td', teacher2).siblings().eq(0).contains('395') - cy.contains('td', teacher2).siblings().eq(2).contains('98.78%') - }) - - it('Teacher search works', () => { - cy.cs('Search').click() - cy.cs('teacher-search').type(teacher1.split(' ')[0]) - cy.get('table tbody tr').should('have.length', 4) - cy.get('table tbody tr').eq(2).contains('td', teacher1) - }) - - it('Can check teacher page', () => { - cy.cs('Search').click() - cy.cs('teacher-search').type(teacher2) - - // Prevent opening in new tab - cy.contains('a', teacher2).invoke('removeAttr', 'target').click() - cy.url().should('include', '/teachers/hy-hlo-49026530') - cy.contains(teacher2) - cy.contains('Syksy 2023').click() - cy.contains('Kevät 2019').click() - cy.contains('tr', 'MAT12004').within(() => { - const rowContent = ['MAT12004', 'Tilastollinen päättely I', '120', '0', '92.31%'] - rowContent.forEach((content, index) => { - cy.get('td').eq(index).contains(content) - }) - }) - }) - - it('Check leaderboad works', () => { - cy.cs('Leaderboard').click() - cy.cs('academic-year').click() - cy.contains('2020-2021').click() - }) -}) diff --git a/cypress/e2e/University.js b/cypress/e2e/University.js deleted file mode 100644 index da7ee021c..000000000 --- a/cypress/e2e/University.js +++ /dev/null @@ -1,101 +0,0 @@ -/// - -const progressLevels = ['bachelors', 'bachelor-masters', 'masters', 'doctoral'] - -const checkProgressBarCharts = () => { - progressLevels.forEach(level => cy.cs(`faculty-${level}-progress-bar-chart-section`)) -} - -const checkProgressTables = () => { - progressLevels.forEach(level => cy.cs(`${level}-faculty-progress-table`)) -} - -const graduationTimesLevels = ['bachelor', 'bcMsCombo', 'master', 'doctor'] - -const checkGraduationCharts = mode => { - graduationTimesLevels.forEach(level => { - cy.cs(`${level}-${mode}-bar-chart`).within(() => { - // Check that bar has loaded - cy.contains('Loading content').should('not.exist') - }) - }) -} - -describe('University view', { defaultCommandTimeout: 60 * 1000 }, () => { - beforeEach(() => { - cy.init('/university') - cy.contains('University') - }) - - describe('Faculty progress tab', () => { - it('contains all the correct progress bar charts', () => { - checkProgressBarCharts() - }) - - it('contains all the correct progress tables', () => { - checkProgressTables() - }) - - it("'All study rights / Special study rights excluded' toggle works", () => { - cy.cs('study-right-toggle').click() - checkProgressBarCharts() - checkProgressTables() - }) - - // Nothing in this test is explained. Non of these values are verified. - it.skip('years in the tables can be clicked to show faculty level breakdown', () => { - cy.cs('study-right-toggle').click() - cy.cs('bachelors-faculty-progress-table-show-button3').click() - cy.contains('29.5%').hover() - cy.contains('Matemaattis-luonnontieteellinen tiedekunta') - cy.contains('H50') - cy.contains('0 Credits: 0') - cy.contains('1 ≤ Credits < 45: 13') - cy.contains('45 ≤ Credits < 90: 10') - cy.contains('90 ≤ Credits < 135: 16') - cy.contains('135 ≤ Credits < 180: 3') - cy.contains('180 ≤ Credits: 2') - }) - - it('info boxes contain correct information', () => { - cy.cs('faculty-progress-info-box-button').click() - cy.cs('faculty-progress-info-box-content').contains('Kuvaa tiedekuntaan kuuluvien') - cy.cs('faculty-bachelor-masters-progress-info-box-button').click() - cy.cs('faculty-bachelor-masters-progress-info-box-content').contains('The starting year is the') - }) - }) - - describe('Faculty graduations tab', () => { - beforeEach(() => { - cy.cs('faculty-graduations-tab').click() - }) - - describe('Different modes work', () => { - it('Breakdown', () => { - cy.cs('graduation-mode-selector').within(() => { - cy.cs('select-breakdown').click() - }) - checkGraduationCharts('breakdown') - }) - - it('Median', () => { - cy.cs('graduation-mode-selector').within(() => { - cy.cs('select-median').click() - }) - checkGraduationCharts('median') - }) - - it('Average', () => { - cy.cs('graduation-mode-selector').within(() => { - cy.cs('select-average').click() - }) - checkGraduationCharts('average') - }) - }) - - it('info boxes contain correct information', () => { - cy.cs('average-graduation-times-info-box-button').hover() - cy.cs('average-graduation-times-info-box-content').contains('Opiskelijoiden keskimääräiset valmistumisajat') - }) - }) -}) diff --git a/cypress/fixtures/completedCoursesData.json b/cypress/fixtures/completedCoursesData.json deleted file mode 100644 index cdca976d0..000000000 --- a/cypress/fixtures/completedCoursesData.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "studentSet1": ["433237", "457144", "458090", "474270", "479440"], - "coursesSet1": ["TKT10001", "TKT10002", "TKT10003", "TKT10004"] -} diff --git a/cypress/fixtures/customPopulations.json b/cypress/fixtures/customPopulations.json deleted file mode 100644 index 61c80cf85..000000000 --- a/cypress/fixtures/customPopulations.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "studentNumbersForCSStudentsSet1": ["433237", "457144", "458090", "465136"], - "studentNumbersForCSStudentsSet2": ["474270", "479440", "470391", "474789"] -} diff --git a/cypress/fixtures/openUniPopulation.json b/cypress/fixtures/openUniPopulation.json deleted file mode 100644 index 52fc77d40..000000000 --- a/cypress/fixtures/openUniPopulation.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "courseCodesSet1": ["TKT10001", "TKT10002"], - "courseCodesSet2": ["TKT10003", "TKT10004", "TKT10005"] -} diff --git a/cypress/fixtures/studyGuidanceGroups.json b/cypress/fixtures/studyGuidanceGroups.json deleted file mode 100644 index 62a862b61..000000000 --- a/cypress/fixtures/studyGuidanceGroups.json +++ /dev/null @@ -1,28 +0,0 @@ -[ - { - "id": "sgg-cypress-1", - "name": { - "fi": "MAT kandit 2020" - }, - "members": [ - { "personStudentNumber": "433237" }, - { "personStudentNumber": "457144" }, - { "personStudentNumber": "458090" } - ], - "tags": { - "studyProgramme": "KH50_001", - "year": "2020" - } - }, - { - "id": "sgg-cypress-2", - "name": { - "fi": "Oma ohjausryhmä" - }, - "members": [{ "personStudentNumber": "474270" }, { "personStudentNumber": "479440" }], - "tags": { - "studyProgramme": null, - "year": null - } - } -] diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index 0c587bf3b..000000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,34 +0,0 @@ -/// -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -/** - * @type {Cypress.PluginConfig} - */ -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config - on('before:browser:launch', (browser = {}, launchOptions) => { - // By manually setting the browser width and height in headless - // mode, screenshots and videos will have a better quality - // https://www.cypress.io/blog/generate-high-resolution-videos-and-screenshots - const width = 2560 - const height = 1440 - - if (browser.name === 'chrome' && browser.isHeadless) { - launchOptions.args.push(`--window-size=${width},${height}`) - launchOptions.args.push('--force-device-scale-factor=1') - } - return launchOptions - }) -} diff --git a/cypress/support/commands.js b/cypress/support/commands.js deleted file mode 100644 index d70cbe13f..000000000 --- a/cypress/support/commands.js +++ /dev/null @@ -1,198 +0,0 @@ -/// -// -// ! IMPORTANT: here we need to set keys to be all lowercase, since -// ! we're replacing headers after they've left browser / frontend. -// All of these users are available in anon user-db -const adminUserHeaders = { - uid: 'admin', - displayname: 'Admin User', - 'shib-session-id': 'mock-cypress-session', - hygroupcn: 'grp-oodikone-users;grp-oodikone-basic-users;grp-toska', - mail: 'grp-toska+mockadminuser@helsinki.fi', - hypersonsisuid: 'hy-hlo-6666666', -} - -const basicUserHeaders = { - uid: 'basic', - displayname: 'Basic User', - 'shib-session-id': 'mock-cypress-session', - hygroupcn: 'grp-oodikone-users;grp-oodikone-basic-users', - mail: 'grp-toska+mockbasicuser@helsinki.fi', - hypersonsisuid: 'hy-hlo-1234567', -} - -const onlycoursestatisticsUserHeaders = { - uid: 'onlycoursestatistics', - displayname: 'Onlycoursestatistics User', - 'shib-session-id': 'mock-cypress-session', - hygroupcn: 'grp-oodikone-basic-users', - mail: 'grp-toska+mockonlycoursestatisticsuser@helsinki.fi', - hypersonsisuid: 'hy-hlo-7654321', -} - -const norightsUserHeaders = { - uid: 'norights', - displayname: 'Norights User', - 'shib-session-id': 'mock-cypress-session', - hygroupcn: 'grp-oodikone-users', - mail: 'grp-toska+mocknorightuser@helsinki.fi', - hypersonsisuid: 'hy-hlo-0000000', -} - -const onlyIamRightsUserHeaders = { - uid: 'onlyiamrights', - displayname: 'Only IAM rights user', - 'shib-session-id': 'mock-cypress-session', - hygroupcn: 'hy-employees;hy-mltdk-mat-jory', - mail: 'grp-toska+mockonlyiamrightsuser@helsinki.fi', - hypersonsisuid: 'hy-hlo-1111111', -} - -// Also has element detail of "KH50_005" for the study guidance groups to work -const onlyStudyGuidanceGroupsUser = { - uid: 'onlystudyguidancegroups', - displayname: 'Study Guidance Groups User', - 'shib-session-id': 'mock-cypress-session', - hygroupcn: 'grp-oodikone-users', - mail: 'grp-toska+mockonlystudyguidancegroupsuser@helsinki.fi', - hypersonsisuid: 'hy-hlo-2222222', -} - -export const userHeaders = [ - adminUserHeaders, - basicUserHeaders, - onlycoursestatisticsUserHeaders, - norightsUserHeaders, - onlyIamRightsUserHeaders, - onlyStudyGuidanceGroupsUser, -] - -/** - * Set up headers to login, set up correct user (admin / basic / etc.) and open given path. - */ -Cypress.Commands.add('init', { prevSubject: false }, (path, userId = 'basic') => { - const headersToUse = userHeaders.find(({ uid }) => uid === userId) - if (!headersToUse) throw Error(`${userId} is not valid user id!`) - - cy.intercept('*', req => { - req.headers = headersToUse - }) - - // TODO: Add wait for visit url. - // This is block by course population query. - cy.visit({ method: 'GET', url: path, headers: headersToUse }) -}) - -/** - * Shorthand for using "Cypress Selectors" (CS), i.e., `data-cy` attributes. - */ -Cypress.Commands.add('cs', { prevSubject: 'optional' }, (subject, name) => { - const selector = `[data-cy="${name}"]` - - if (subject === undefined) { - return cy.get(selector) - } - return cy.wrap(subject).find(selector) -}) - -/** - * Select item from FilterSelect dropdown. - * If the index is a number, select index-th item. - * Otherwise select the item containing index text. - */ -Cypress.Commands.add('selectFromDropdown', { prevSubject: false }, (label, index, isMultiSelect = false) => { - cy.cs(`${label}-selector`).click() - - cy.get(`[role="listbox"][aria-labelledby="${label}"]`).within(() => { - if (typeof index === 'number') cy.get('li').eq(index).click() - else cy.get('li').contains(index).click() - }) - - if (isMultiSelect) cy.get('#menu- > .MuiModal-backdrop').click() -}) - -/** - * Select item from FilterSearchableSelect dropdown. - * If the index is a number, select index-th item. - * Otherwise select the item containing index text. - */ -Cypress.Commands.add('selectFromAutocomplete', { prevSubject: false }, (label, index) => { - cy.cs(`${label}-selector`).click() - cy.get(`#${label}-popper.MuiAutocomplete-popper [role="listbox"]`).within(() => { - if (typeof index === 'number') cy.get('li').eq(index).click() - else cy.get('li').contains(index).click() - }) -}) - -/** - * Set range selector values FilterRange. - * If the reset flag is set, the function tries to reset the original values. - */ -Cypress.Commands.add('setRangeSelect', { prevSubject: false }, (filter, min, max, expected, reset) => { - const minText = min.toString() - const maxText = max.toString() - const expectedText = expected.toString() - - const parent = `${filter}-filter-card` - - cy.cs(parent) - .cs('FilterRangeStart') - .find('input') - .invoke('val') - .then(initialMin => { - cy.cs(parent) - .cs('FilterRangeEnd') - .find('input') - .invoke('val') - .then(initialMax => { - cy.cs(parent).cs('FilterRangeStart').find('input').clear() - cy.cs(parent).cs('FilterRangeStart').find('input').type(minText) - cy.cs(parent).cs('FilterRangeEnd').find('input').clear() - cy.cs(parent).cs('FilterRangeEnd').find('input').type(maxText) - - // This should be linked to other checking functions. - // Maybe one day. - cy.contains(`Students (${expectedText})`) - - if (reset) { - cy.cs(parent).cs('FilterRangeStart').find('input').clear() - cy.cs(parent).cs('FilterRangeStart').find('input').type(initialMin) - cy.cs(parent).cs('FilterRangeEnd').find('input').clear() - cy.cs(parent).cs('FilterRangeEnd').find('input')?.type(initialMax) - } - }) - }) -}) - -Cypress.Commands.add('checkTableStats', (correctStats, tableName) => { - cy.get(`[data-cy=${tableName}-data-table] tbody`).within(() => { - correctStats.forEach((values, trIndex) => { - cy.get('tr') - .filter(':visible') - .eq(trIndex) - .within(() => { - values.forEach((value, tdIndex) => { - cy.get('td').eq(tdIndex).contains(value) - }) - }) - }) - cy.get('tr').filter(':visible').should('have.length', correctStats.length) - }) -}) - -/** - * Hover on the selected element. - */ -Cypress.Commands.add('hover', { prevSubject: 'element' }, (subject, options = {}) => { - cy.wrap(subject).trigger('mouseover', { - bubbles: true, - cancelable: true, - ...options, - }) - - cy.wrap(subject).trigger('mousemove', { - bubbles: true, - cancelable: true, - ...options, - }) -}) diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js deleted file mode 100644 index e21a29250..000000000 --- a/cypress/support/e2e.js +++ /dev/null @@ -1,21 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -require('./commands') - -Cypress.on('uncaught:exception', error => { - /* returning false here prevents Cypress from failing the test */ - return true -}) diff --git a/package-lock.json b/package-lock.json index 0bd2868b8..38911adb5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,6 @@ "license": "ISC", "devDependencies": { "@playwright/test": "1.61.0", - "cypress": "15.18.1", - "eslint-plugin-cypress": "^6.2.3", "eslint-plugin-import-x": "^4.16.1", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", @@ -275,56 +273,6 @@ "postcss-selector-parser": "^7.1.1" } }, - "node_modules/@cypress/request": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-4.0.1.tgz", - "integrity": "sha512-y20e+e6dFYkOUUJLVUZTsJRuTiXZaUQ32WD+R/ux/HBybbTx4ge7cNINcua0pU8+SNkKuRbOF12mBmzuzM8n5w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~4.0.4", - "http-signature": "~1.4.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "performance-now": "^2.1.0", - "qs": "^6.15.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "^5.0.0", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" - } - }, - "node_modules/@cypress/xvfb/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/@emnapi/core": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", @@ -1495,27 +1443,6 @@ "license": "MIT", "peer": true }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/sizzle": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.10.tgz", - "integrity": "sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tmp": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.6.tgz", - "integrity": "sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==", - "dev": true, - "license": "MIT" - }, "node_modules/@typescript-eslint/types": { "version": "8.43.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", @@ -1884,27 +1811,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2050,26 +1956,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -2090,23 +1976,6 @@ "node": ">= 0.4" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2123,23 +1992,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", - "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", - "dev": true, - "license": "MIT" - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2147,44 +1999,6 @@ "dev": true, "license": "MIT" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/blob-util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -2209,31 +2023,6 @@ "node": ">=8" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/cacheable": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.4.tgz", @@ -2258,16 +2047,6 @@ "@keyv/serialize": "^1.1.1" } }, - "node_modules/cachedir": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", - "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -2328,19 +2107,13 @@ "node": ">=6" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2352,22 +2125,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", @@ -2384,22 +2141,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "colors": "1.4.0" - } - }, "node_modules/cli-truncate": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", @@ -2497,40 +2238,6 @@ "dev": true, "license": "MIT" }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", @@ -2541,16 +2248,6 @@ "node": ">= 12.0.0" } }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2558,13 +2255,6 @@ "dev": true, "license": "MIT" }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "license": "MIT" - }, "node_modules/cosmiconfig": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", @@ -2598,6 +2288,7 @@ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2644,104 +2335,6 @@ "node": ">=4" } }, - "node_modules/cypress": { - "version": "15.18.1", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-15.18.1.tgz", - "integrity": "sha512-JtkTVtUE2lvLYgZCaug+Uai0H9IqsJirlBO49c87QwG0bJUGvAUVBz1EJve0b0oaYP244Ew9M0BkrHpcqkYxmw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@cypress/request": "^4.0.0", - "@cypress/xvfb": "^1.2.4", - "@types/sinonjs__fake-timers": "8.1.1", - "@types/sizzle": "^2.3.2", - "@types/tmp": "^0.2.3", - "arch": "^2.2.0", - "blob-util": "^2.0.2", - "bluebird": "^3.7.2", - "buffer": "^5.7.1", - "cachedir": "^2.4.0", - "chalk": "^4.1.0", - "ci-info": "^4.1.0", - "cli-table3": "0.6.1", - "commander": "^6.2.1", - "common-tags": "^1.8.0", - "dayjs": "^1.10.4", - "debug": "^4.3.4", - "eventemitter2": "6.4.7", - "execa": "4.1.0", - "executable": "^4.1.1", - "fs-extra": "^9.1.0", - "hasha": "5.2.2", - "is-installed-globally": "~0.4.0", - "listr2": "^9.0.5", - "lodash": "^4.17.23", - "log-symbols": "^4.0.0", - "minimist": "^1.2.8", - "ospath": "^1.2.2", - "pretty-bytes": "^5.6.0", - "process": "^0.11.10", - "proxy-from-env": "1.0.0", - "request-progress": "^3.0.0", - "supports-color": "^8.1.1", - "systeminformation": "^5.31.1", - "tmp": "~0.2.4", - "tree-kill": "1.2.2", - "tslib": "1.14.1", - "untildify": "^4.0.0", - "yauzl": "^3.3.1" - }, - "bin": { - "cypress": "bin/cypress" - }, - "engines": { - "node": "^20.1.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/cypress/node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cypress/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/cypress/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -2796,13 +2389,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/dayjs": { - "version": "1.11.13", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", - "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", - "dev": true, - "license": "MIT" - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -2865,16 +2451,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -2903,17 +2479,6 @@ "node": ">= 0.4" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2921,16 +2486,6 @@ "dev": true, "license": "MIT" }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -3242,19 +2797,6 @@ } } }, - "node_modules/eslint-plugin-cypress": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-6.2.3.tgz", - "integrity": "sha512-Z2NqobTABOWJDga9bvmhZawAhRbEkgIk+HZPP95rF6B/AnS1o4vCXNmtfrs3J4evirHSHmPGKXj3Ty1nqXP0MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "globals": "^17.4.0" - }, - "peerDependencies": { - "eslint": ">=9" - } - }, "node_modules/eslint-plugin-import-x": { "version": "4.16.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.1.tgz", @@ -3484,13 +3026,6 @@ "node": ">=0.10.0" } }, - "node_modules/eventemitter2": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", - "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", - "dev": true, - "license": "MIT" - }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", @@ -3498,60 +3033,6 @@ "dev": true, "license": "MIT" }, - "node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3725,49 +3206,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", - "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.4", - "mime-types": "^2.1.35" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -3876,22 +3314,6 @@ "node": ">= 0.4" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-symbol-description": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", @@ -3923,16 +3345,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3947,22 +3359,6 @@ "node": ">=10.13.0" } }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -4105,13 +3501,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -4131,6 +3520,7 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -4193,23 +3583,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/hashery": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", @@ -4256,31 +3629,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/http-signature": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", - "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.18.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8.12.0" - } - }, "node_modules/husky": { "version": "9.1.7", "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", @@ -4297,27 +3645,6 @@ "url": "https://github.com/sponsors/typicode" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4368,16 +3695,6 @@ "node": ">=0.8.19" } }, - "node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -4603,23 +3920,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -4673,16 +3973,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -4741,19 +4031,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-string": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", @@ -4805,26 +4082,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-weakmap": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", @@ -4885,13 +4142,6 @@ "dev": true, "license": "ISC" }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "license": "MIT" - }, "node_modules/iterator.prototype": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", @@ -4930,13 +4180,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "license": "MIT" - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -4952,13 +4195,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4975,42 +4211,6 @@ "license": "MIT", "peer": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC" - }, - "node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -5169,13 +4369,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5184,13 +4377,6 @@ "license": "MIT", "peer": true }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", @@ -5198,23 +4384,6 @@ "dev": true, "license": "MIT" }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/log-update": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", @@ -5364,13 +4533,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5395,39 +4557,6 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/mimic-function": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", @@ -5454,16 +4583,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5537,19 +4656,6 @@ "node": ">=0.10.0" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5658,32 +4764,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -5703,13 +4783,6 @@ "node": ">= 0.8.0" } }, - "node_modules/ospath": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", - "dev": true, - "license": "MIT" - }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -5930,6 +5003,7 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -5941,20 +5015,6 @@ "dev": true, "license": "MIT" }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, - "license": "MIT" - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -5988,16 +5048,6 @@ "node": ">=0.10" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/playwright": { "version": "1.61.0", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.0.tgz", @@ -6144,29 +5194,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -6179,24 +5206,6 @@ "react-is": "^16.13.1" } }, - "node_modules/proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", - "dev": true, - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -6228,23 +5237,6 @@ "dev": true, "license": "MIT" }, - "node_modules/qs": { - "version": "6.15.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", - "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "es-define-property": "^1.0.1", - "side-channel": "^1.1.1" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -6317,16 +5309,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/request-progress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "throttleit": "^1.0.0" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -6465,27 +5447,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/safe-push-apply": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", @@ -6521,13 +5482,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -6593,6 +5547,7 @@ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -6606,6 +5561,7 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -6686,13 +5642,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, "node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", @@ -6762,32 +5711,6 @@ "node": ">=0.10.0" } }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stable-hash-x": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", @@ -6948,16 +5871,6 @@ "node": ">=8" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -7166,6 +6079,7 @@ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -7235,33 +6149,6 @@ "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, - "node_modules/systeminformation": { - "version": "5.31.5", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.5.tgz", - "integrity": "sha512-5SyLdip4/3alxD4Kh+63bUQTJmu7YMfYQTC+koZy7X73HgNqZSD2P4wOZQWtUncvPvcEmnfIjCoygN4MRoEejQ==", - "dev": true, - "license": "MIT", - "os": [ - "darwin", - "linux", - "win32", - "freebsd", - "openbsd", - "netbsd", - "sunos", - "android" - ], - "bin": { - "systeminformation": "lib/cli.js" - }, - "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "Buy me a coffee", - "url": "https://www.buymeacoffee.com/systeminfo" - } - }, "node_modules/table": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", @@ -7321,16 +6208,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/throttleit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", - "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tinypool": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz", @@ -7341,36 +6218,6 @@ "node": "^20.0.0 || >=22.0.0" } }, - "node_modules/tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tldts-core": "^6.1.86" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/tmp": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -7384,29 +6231,6 @@ "node": ">=8.0" } }, - "node_modules/tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tldts": "^6.1.32" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "license": "MIT", - "bin": { - "tree-kill": "cli.js" - } - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -7415,26 +6239,6 @@ "license": "0BSD", "optional": true }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "license": "Unlicense" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7449,16 +6253,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", @@ -7569,16 +6363,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/unrs-resolver": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", @@ -7614,16 +6398,6 @@ "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -7642,27 +6416,13 @@ "dev": true, "license": "MIT" }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -7858,13 +6618,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, "node_modules/write-file-atomic": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz", @@ -7904,19 +6657,6 @@ "node": ">= 14.6" } }, - "node_modules/yauzl": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.4.0.tgz", - "integrity": "sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 1c11fea46..90bb49c19 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,6 @@ "node": ">=24.0.0" }, "scripts": { - "cypress": "cypress", - "cypress:run": "cypress run --browser firefox", "playwright": "playwright test -c playwright.config.ts", "playwright:ui": "playwright test --ui -c playwright.config.ts", "playwright:headed": "playwright test --headed -c playwright.config.ts", @@ -46,14 +44,9 @@ "bugs": { "url": "https://github.com/UniversityOfHelsinkiCS/oodikone/issues" }, - "allowScripts": { - "cypress": true - }, "homepage": "https://github.com/UniversityOfHelsinkiCS/oodikone#readme", "devDependencies": { "@playwright/test": "1.61.0", - "cypress": "15.18.1", - "eslint-plugin-cypress": "^6.2.3", "eslint-plugin-import-x": "^4.16.1", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0",