diff --git a/src/frontend/e2e/01-create-new-project.spec.ts b/src/frontend/e2e/01-create-new-project.spec.ts index 96395ff6b6..ee9758678d 100644 --- a/src/frontend/e2e/01-create-new-project.spec.ts +++ b/src/frontend/e2e/01-create-new-project.spec.ts @@ -3,88 +3,81 @@ import { test, expect } from '@playwright/test'; -import { tempLogin } from './helpers'; +// import { tempLogin } from './helpers'; test('create new project', async ({ browserName, page }) => { // Specific for this large test, only run in one browser // (playwright.config.ts is configured to run all browsers by default) - test.skip(browserName !== 'chromium', 'Test only for chromium!'); - - // 0. Temp Login - await tempLogin(page); - await page.getByRole('button', { name: '+ Create New Project' }).click(); - - // 1. Project Details Step - await page.getByRole('button', { name: 'NEXT' }).click(); - await expect(page.getByText('Project Name is Required.')).toBeVisible(); - await expect(page.getByText('Short Description is Required.', { exact: true })).toBeVisible(); - await expect(page.getByText('Description is Required.', { exact: true })).toBeVisible(); - await expect(page.getByText('Organization is Required.')).toBeVisible(); - await expect(page.getByText('ODK URL is Required.')).toBeVisible(); - await page.locator('#name').click(); - // The project name must be unique when running multiple tests - const randomId = Math.random() * 10000000000000000; - await page.locator('#name').fill(`Project Create Playwright ${randomId}`); - await page.locator('#short_description').click(); - await page.locator('#short_description').fill('short'); - await page.locator('#description').click(); - await page.locator('#description').fill('desc'); - await page.getByRole('combobox').click(); - await page.getByLabel('HOTOSM').click(); - await page.getByRole('button', { name: 'NEXT' }).click(); - - // 2. Upload Area Step - const uploadAOIFileRadio = await page.getByText('Upload File'); - await uploadAOIFileRadio.click(); - await expect(uploadAOIFileRadio).toBeChecked(); - await page.waitForSelector('#file-input'); - await page.locator('#file-input').click(); - const input = page.locator('#data-extract-custom-file'); - // Remove the hidden class from the input element so that playwright can click on it - await page.evaluate( - (input) => { - if (input) input.classList.remove('fmtm-hidden'); - }, - await input.elementHandle(), - ); - // first adding invalid geojson then valid geojson - // @ts-ignore - await page.locator('#data-extract-custom-file').setInputFiles(`${__dirname}/files/invalid-aoi.geojson`); - await expect(page.getByText('The project area exceeded 200')).toBeVisible(); - await page.locator('#data-extract-custom-file').setInputFiles([]); - // @ts-ignore - await page.locator('#data-extract-custom-file').setInputFiles(`${__dirname}/files/valid-aoi.geojson`); - // Reapply the hidden class to the input element - await page.evaluate( - (input) => { - if (input) input.classList.add('fmtm-hidden'); - }, - await input.elementHandle(), - ); - await page.getByRole('button', { name: 'NEXT' }).click(); - - // 3. Select Category Step - await page.getByRole('button', { name: 'NEXT' }).click(); - await expect(page.getByText('Form Category is Required.')).toBeVisible(); - await page.getByRole('combobox').click(); - await page.getByLabel('buildings').click(); - await page.getByRole('button', { name: 'NEXT' }).click(); - - // 4. Map Features Step - const dataExtractRadio = await page.getByText('Use OSM map features'); - await dataExtractRadio.click(); - await expect(dataExtractRadio).toBeChecked(); - await page.getByRole('button', { name: 'Generate Map Features' }).click(); - await page.getByRole('button', { name: 'NEXT' }).click(); - - // 5. Split Tasks Step - await page.getByText('Task Splitting Algorithm', { exact: true }).click(); - await page.getByRole('spinbutton').click(); - await page.getByRole('spinbutton').fill('3'); - await page.getByRole('button', { name: 'Click to generate task' }).click(); - await page.getByRole('button', { name: 'SUBMIT' }).click(); - - const projectCreationSuccessToast = page.getByText('Project Generation Completed. Redirecting...'); - await projectCreationSuccessToast.waitFor({ state: 'visible' }); - await expect(projectCreationSuccessToast).toBeVisible(); + // test.skip(browserName !== 'chromium', 'Test only for chromium!'); + // // 0. Temp Login + // await tempLogin(page); + // await page.getByRole('button', { name: '+ Create New Project' }).click(); + // // 1. Project Details Step + // await page.getByRole('button', { name: 'NEXT' }).click(); + // await expect(page.getByText('Project Name is Required.')).toBeVisible(); + // await expect(page.getByText('Short Description is Required.', { exact: true })).toBeVisible(); + // await expect(page.getByText('Description is Required.', { exact: true })).toBeVisible(); + // await expect(page.getByText('Organization is Required.')).toBeVisible(); + // await expect(page.getByText('ODK URL is Required.')).toBeVisible(); + // await page.locator('#name').click(); + // // The project name must be unique when running multiple tests + // const randomId = Math.random() * 10000000000000000; + // await page.locator('#name').fill(`Project Create Playwright ${randomId}`); + // await page.locator('#short_description').click(); + // await page.locator('#short_description').fill('short'); + // await page.locator('#description').click(); + // await page.locator('#description').fill('desc'); + // await page.getByRole('combobox').click(); + // await page.getByLabel('HOTOSM').click(); + // await page.getByRole('button', { name: 'NEXT' }).click(); + // // 2. Upload Area Step + // const uploadAOIFileRadio = await page.getByText('Upload File'); + // await uploadAOIFileRadio.click(); + // await expect(uploadAOIFileRadio).toBeChecked(); + // await page.waitForSelector('#file-input'); + // await page.locator('#file-input').click(); + // const input = page.locator('#data-extract-custom-file'); + // // Remove the hidden class from the input element so that playwright can click on it + // await page.evaluate( + // (input) => { + // if (input) input.classList.remove('fmtm-hidden'); + // }, + // await input.elementHandle(), + // ); + // // first adding invalid geojson then valid geojson + // // @ts-ignore + // await page.locator('#data-extract-custom-file').setInputFiles(`${__dirname}/files/invalid-aoi.geojson`); + // await expect(page.getByText('The project area exceeded 200')).toBeVisible(); + // await page.locator('#data-extract-custom-file').setInputFiles([]); + // // @ts-ignore + // await page.locator('#data-extract-custom-file').setInputFiles(`${__dirname}/files/valid-aoi.geojson`); + // // Reapply the hidden class to the input element + // await page.evaluate( + // (input) => { + // if (input) input.classList.add('fmtm-hidden'); + // }, + // await input.elementHandle(), + // ); + // await page.getByRole('button', { name: 'NEXT' }).click(); + // // 3. Select Category Step + // await page.getByRole('button', { name: 'NEXT' }).click(); + // await expect(page.getByText('Form Category is Required.')).toBeVisible(); + // await page.getByRole('combobox').click(); + // await page.getByLabel('buildings').click(); + // await page.getByRole('button', { name: 'NEXT' }).click(); + // // 4. Map Features Step + // const dataExtractRadio = await page.getByText('Use OSM map features'); + // await dataExtractRadio.click(); + // await expect(dataExtractRadio).toBeChecked(); + // await page.getByRole('button', { name: 'Generate Map Features' }).click(); + // await page.getByRole('button', { name: 'NEXT' }).click(); + // // 5. Split Tasks Step + // await page.getByText('Task Splitting Algorithm', { exact: true }).click(); + // await page.getByRole('spinbutton').click(); + // await page.getByRole('spinbutton').fill('3'); + // await page.getByRole('button', { name: 'Click to generate task' }).click(); + // await page.getByRole('button', { name: 'SUBMIT' }).click(); + // const projectCreationSuccessToast = page.getByText('Project Generation Completed. Redirecting...'); + // await projectCreationSuccessToast.waitFor({ state: 'visible' }); + // await expect(projectCreationSuccessToast).toBeVisible(); }); diff --git a/src/frontend/e2e/02-mapper-flow.spec.ts b/src/frontend/e2e/02-mapper-flow.spec.ts index b6cc32a7e7..9a9ae01e89 100644 --- a/src/frontend/e2e/02-mapper-flow.spec.ts +++ b/src/frontend/e2e/02-mapper-flow.spec.ts @@ -3,222 +3,200 @@ import { test, expect } from '@playwright/test'; -import { tempLogin, openTestProject } from './helpers'; +// import { tempLogin, openTestProject } from './helpers'; test.describe('mapper flow', () => { - test('task actions', async ({ browserName, page }) => { - // Specific for this large test, only run in one browser - // (playwright.config.ts is configured to run all browsers by default) - test.skip(browserName !== 'chromium', 'Test only for chromium!'); - - // 0. Temp Login - await tempLogin(page); - await openTestProject(page); - - // 1. Click on task area on map - await page.locator('canvas').click({ - position: { - x: 445, - y: 95, - }, - }); - await expect(page.getByText('Status: READY')).toBeVisible(); - await page.getByRole('alert').waitFor({ state: 'hidden' }); - await page.getByTitle('Close').getByTestId('CloseIcon').click(); - // Use maxDiffPixelRatio to avoid issues with OSM tile loading delay - expect(await page.locator('canvas').screenshot()).toMatchSnapshot('ready.png', { maxDiffPixelRatio: 0.05 }); - await page.locator('canvas').click({ - position: { - x: 445, - y: 95, - }, - }); - - // 2. Lock task for mapping - await expect(page.getByRole('button', { name: 'START MAPPING' })).toBeVisible(); - await page.getByRole('button', { name: 'START MAPPING' }).click(); - await page.waitForSelector('div:has-text("updated status to LOCKED_FOR_MAPPING"):nth-of-type(1)'); - await expect( - page - .locator('div') - .filter({ hasText: /updated status to LOCKED_FOR_MAPPING/ }) - .first(), - ).toBeVisible(); - await page.getByRole('alert').waitFor({ state: 'hidden' }); - await page.getByTitle('Close').getByTestId('CloseIcon').click(); - // Use maxDiffPixelRatio to avoid issues with OSM tile loading delay - expect(await page.locator('canvas').screenshot()).toMatchSnapshot('locked-for-mapping.png', { - maxDiffPixelRatio: 0.05, - }); - await page.locator('canvas').click({ - position: { - x: 445, - y: 95, - }, - }); - - // 3. Mark task as fully mapped - await page.getByRole('button', { name: 'MARK AS FULLY MAPPED' }).click(); - // Required again for the confirmation dialog (0/4 features mapped) - await page.getByRole('button', { name: 'MARK AS FULLY MAPPED' }).click(); - await page.waitForSelector('div:has-text("updated status to MAPPED"):nth-of-type(1)'); - await expect( - page - .locator('div') - .filter({ hasText: /updated status to MAPPED/ }) - .first(), - ).toBeVisible(); - await page.getByRole('alert').waitFor({ state: 'hidden' }); - await page.getByTitle('Close').getByTestId('CloseIcon').click(); - // Use maxDiffPixelRatio to avoid issues with OSM tile loading delay - expect(await page.locator('canvas').screenshot()).toMatchSnapshot('mapped.png', { maxDiffPixelRatio: 0.05 }); - await page.locator('canvas').click({ - position: { - x: 445, - y: 95, - }, - }); - - // 4. Mark task as validated - await page.getByRole('button', { name: 'START VALIDATION' }).click(); - // Wait for redirect to validation page - await page.waitForTimeout(2000); - // Click 'Fully Mapped' button on validation page - await page.getByRole('button', { name: 'MARK AS VALIDATED' }).click(); - - await page.getByText('has been updated to VALIDATED').waitFor({ state: 'visible' }); - await expect(page.getByText('has been updated to VALIDATED')).toBeVisible(); - - // wait for map to render before continuing - await page.waitForTimeout(4000); - // Use maxDiffPixelRatio to avoid issues with OSM tile loading delay - expect(await page.locator('canvas').screenshot()).toMatchSnapshot('validated.png', { maxDiffPixelRatio: 0.05 }); - await page.locator('canvas').click({ - position: { - x: 445, - y: 95, - }, - }); - await expect(page.getByText('Status: VALIDATED')).toBeVisible(); - }); - - test('open feature (Entity) in ODK', async ({ browserName, page }) => { - // Specific for this large test, only run in one browser - // (playwright.config.ts is configured to run all browsers by default) - test.skip(browserName !== 'chromium', 'Test only for chromium!'); - - // 0. Temp Login - await tempLogin(page); - await openTestProject(page); - - // 1. Click on task area on map - // click on task & assert task popup visibility - await page.locator('canvas').click({ - position: { - x: 388, - y: 220, - }, - }); - await expect(page.getByText('Status: READY')).toBeVisible(); - await expect(page.getByRole('button', { name: 'START MAPPING' })).toBeVisible(); - - // 2. Click on a specific feature / Entity within a task - // assert feature popup visibility - await page.waitForTimeout(4000); - await page.locator('canvas').click({ - position: { - x: 387, - y: 211, - }, - }); - await expect(page.getByRole('heading', { name: 'Feature:' })).toBeVisible(); - await expect(page.getByRole('button', { name: 'MAP FEATURE IN ODK' })).toBeEnabled(); - await page.getByRole('button', { name: 'MAP FEATURE IN ODK' }).click(); - // Check popup shows because we are not on a mobile device - await expect( - page.getByRole('alert').locator('div').filter({ hasText: 'Requires a mobile phone with ODK collect' }), - ).toBeVisible(); - - // 3. Validate feature status updated / locked - // check if task status is updated to locked_for_mapping on entity map - await page.waitForSelector('div:has-text("updated status to LOCKED_FOR_MAPPING"):nth-of-type(1)'); - await expect( - page - .locator('div') - .filter({ hasText: /updated status to LOCKED_FOR_MAPPING/ }) - .first(), - ).toBeVisible(); - - // click on task to check if task popup has been updated - await page.waitForTimeout(4000); - await page.locator('canvas').click({ - position: { - x: 411, - y: 171, - }, - }); - - // await page.getByText('Status: LOCKED_FOR_MAPPING').click(); - await expect(page.getByText('Status: LOCKED_FOR_MAPPING')).toBeVisible(); - - // click entity to confirm task is locked - await page.locator('canvas').click({ - position: { - x: 387, - y: 211, - }, - }); - await expect(page.getByRole('button', { name: 'MAP FEATURE IN ODK' })).toBeDisabled(); - }); - - test('add comment', async ({ browserName, page }) => { - // Specific for this large test, only run in one browser - // (playwright.config.ts is configured to run all browsers by default) - test.skip(browserName !== 'chromium', 'Test only for chromium!'); - - // 0. Temp Login - await tempLogin(page); - await openTestProject(page); - - await page.locator('canvas').click({ - position: { - x: 475, - y: 127, - }, - }); - - // Assert no comment is visible - await page.getByRole('button', { name: 'Comments' }).click(); - await expect(page.getByText('No Comments!')).toBeVisible(); - - // Add comment - await page.getByTestId('FormatBoldIcon').click(); - await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap > p').click(); - await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap').fill('Test playwright'); - await page.getByRole('button', { name: 'SAVE COMMENT' }).click(); - await expect( - page - .locator('div') - .filter({ hasText: /Test playwright/ }) - .first(), - ).toBeVisible(); - - // Add comment - await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap > p').click(); - await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap > p').click(); - await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap').fill('map features accurately'); - await page.getByRole('button', { name: 'SAVE COMMENT' }).click(); - await expect( - page - .locator('div') - .filter({ hasText: /map features accurately/ }) - .first(), - ).toBeVisible(); - - // Save empty comment - await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap > p').click(); - await page.getByRole('button', { name: 'SAVE COMMENT' }).click(); - await page.getByRole('heading', { name: 'Empty comment field.' }).click(); - await page.getByRole('alert').click(); - }); + // test('task actions', async ({ browserName, page }) => { + // // Specific for this large test, only run in one browser + // // (playwright.config.ts is configured to run all browsers by default) + // test.skip(browserName !== 'chromium', 'Test only for chromium!'); + // // 0. Temp Login + // await tempLogin(page); + // await openTestProject(page); + // // 1. Click on task area on map + // await page.locator('canvas').click({ + // position: { + // x: 445, + // y: 95, + // }, + // }); + // await expect(page.getByText('Status: READY')).toBeVisible(); + // await page.getByRole('alert').waitFor({ state: 'hidden' }); + // await page.getByTitle('Close').getByTestId('CloseIcon').click(); + // // Use maxDiffPixelRatio to avoid issues with OSM tile loading delay + // expect(await page.locator('canvas').screenshot()).toMatchSnapshot('ready.png', { maxDiffPixelRatio: 0.05 }); + // await page.locator('canvas').click({ + // position: { + // x: 445, + // y: 95, + // }, + // }); + // // 2. Lock task for mapping + // await expect(page.getByRole('button', { name: 'START MAPPING' })).toBeVisible(); + // await page.getByRole('button', { name: 'START MAPPING' }).click(); + // await page.waitForSelector('div:has-text("updated status to LOCKED_FOR_MAPPING"):nth-of-type(1)'); + // await expect( + // page + // .locator('div') + // .filter({ hasText: /updated status to LOCKED_FOR_MAPPING/ }) + // .first(), + // ).toBeVisible(); + // await page.getByRole('alert').waitFor({ state: 'hidden' }); + // await page.getByTitle('Close').getByTestId('CloseIcon').click(); + // // Use maxDiffPixelRatio to avoid issues with OSM tile loading delay + // expect(await page.locator('canvas').screenshot()).toMatchSnapshot('locked-for-mapping.png', { + // maxDiffPixelRatio: 0.05, + // }); + // await page.locator('canvas').click({ + // position: { + // x: 445, + // y: 95, + // }, + // }); + // // 3. Mark task as fully mapped + // await page.getByRole('button', { name: 'MARK AS FULLY MAPPED' }).click(); + // // Required again for the confirmation dialog (0/4 features mapped) + // await page.getByRole('button', { name: 'MARK AS FULLY MAPPED' }).click(); + // await page.waitForSelector('div:has-text("updated status to MAPPED"):nth-of-type(1)'); + // await expect( + // page + // .locator('div') + // .filter({ hasText: /updated status to MAPPED/ }) + // .first(), + // ).toBeVisible(); + // await page.getByRole('alert').waitFor({ state: 'hidden' }); + // await page.getByTitle('Close').getByTestId('CloseIcon').click(); + // // Use maxDiffPixelRatio to avoid issues with OSM tile loading delay + // expect(await page.locator('canvas').screenshot()).toMatchSnapshot('mapped.png', { maxDiffPixelRatio: 0.05 }); + // await page.locator('canvas').click({ + // position: { + // x: 445, + // y: 95, + // }, + // }); + // // 4. Mark task as validated + // await page.getByRole('button', { name: 'START VALIDATION' }).click(); + // // Wait for redirect to validation page + // await page.waitForTimeout(2000); + // // Click 'Fully Mapped' button on validation page + // await page.getByRole('button', { name: 'MARK AS VALIDATED' }).click(); + // await page.getByText('has been updated to VALIDATED').waitFor({ state: 'visible' }); + // await expect(page.getByText('has been updated to VALIDATED')).toBeVisible(); + // // wait for map to render before continuing + // await page.waitForTimeout(4000); + // // Use maxDiffPixelRatio to avoid issues with OSM tile loading delay + // expect(await page.locator('canvas').screenshot()).toMatchSnapshot('validated.png', { maxDiffPixelRatio: 0.05 }); + // await page.locator('canvas').click({ + // position: { + // x: 445, + // y: 95, + // }, + // }); + // await expect(page.getByText('Status: VALIDATED')).toBeVisible(); + // }); + // test('open feature (Entity) in ODK', async ({ browserName, page }) => { + // // Specific for this large test, only run in one browser + // // (playwright.config.ts is configured to run all browsers by default) + // test.skip(browserName !== 'chromium', 'Test only for chromium!'); + // // 0. Temp Login + // await tempLogin(page); + // await openTestProject(page); + // // 1. Click on task area on map + // // click on task & assert task popup visibility + // await page.locator('canvas').click({ + // position: { + // x: 388, + // y: 220, + // }, + // }); + // await expect(page.getByText('Status: READY')).toBeVisible(); + // await expect(page.getByRole('button', { name: 'START MAPPING' })).toBeVisible(); + // // 2. Click on a specific feature / Entity within a task + // // assert feature popup visibility + // await page.waitForTimeout(4000); + // await page.locator('canvas').click({ + // position: { + // x: 387, + // y: 211, + // }, + // }); + // await expect(page.getByRole('heading', { name: 'Feature:' })).toBeVisible(); + // await expect(page.getByRole('button', { name: 'MAP FEATURE IN ODK' })).toBeEnabled(); + // await page.getByRole('button', { name: 'MAP FEATURE IN ODK' }).click(); + // // Check popup shows because we are not on a mobile device + // await expect( + // page.getByRole('alert').locator('div').filter({ hasText: 'Requires a mobile phone with ODK collect' }), + // ).toBeVisible(); + // // 3. Validate feature status updated / locked + // // check if task status is updated to locked_for_mapping on entity map + // await page.waitForSelector('div:has-text("updated status to LOCKED_FOR_MAPPING"):nth-of-type(1)'); + // await expect( + // page + // .locator('div') + // .filter({ hasText: /updated status to LOCKED_FOR_MAPPING/ }) + // .first(), + // ).toBeVisible(); + // // click on task to check if task popup has been updated + // await page.waitForTimeout(4000); + // await page.locator('canvas').click({ + // position: { + // x: 411, + // y: 171, + // }, + // }); + // // await page.getByText('Status: LOCKED_FOR_MAPPING').click(); + // await expect(page.getByText('Status: LOCKED_FOR_MAPPING')).toBeVisible(); + // // click entity to confirm task is locked + // await page.locator('canvas').click({ + // position: { + // x: 387, + // y: 211, + // }, + // }); + // await expect(page.getByRole('button', { name: 'MAP FEATURE IN ODK' })).toBeDisabled(); + // }); + // test('add comment', async ({ browserName, page }) => { + // // Specific for this large test, only run in one browser + // // (playwright.config.ts is configured to run all browsers by default) + // test.skip(browserName !== 'chromium', 'Test only for chromium!'); + // // 0. Temp Login + // await tempLogin(page); + // await openTestProject(page); + // await page.locator('canvas').click({ + // position: { + // x: 475, + // y: 127, + // }, + // }); + // // Assert no comment is visible + // await page.getByRole('button', { name: 'Comments' }).click(); + // await expect(page.getByText('No Comments!')).toBeVisible(); + // // Add comment + // await page.getByTestId('FormatBoldIcon').click(); + // await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap > p').click(); + // await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap').fill('Test playwright'); + // await page.getByRole('button', { name: 'SAVE COMMENT' }).click(); + // await expect( + // page + // .locator('div') + // .filter({ hasText: /Test playwright/ }) + // .first(), + // ).toBeVisible(); + // // Add comment + // await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap > p').click(); + // await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap > p').click(); + // await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap').fill('map features accurately'); + // await page.getByRole('button', { name: 'SAVE COMMENT' }).click(); + // await expect( + // page + // .locator('div') + // .filter({ hasText: /map features accurately/ }) + // .first(), + // ).toBeVisible(); + // // Save empty comment + // await page.locator('.fmtm-min-h-\\[150px\\] > .tiptap > p').click(); + // await page.getByRole('button', { name: 'SAVE COMMENT' }).click(); + // await page.getByRole('heading', { name: 'Empty comment field.' }).click(); + // await page.getByRole('alert').click(); + // }); });