diff --git a/.gitignore b/.gitignore index bce9fc7231..6d630bf21d 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,7 @@ tests/qgis-projects/webdav/test/* !tests/qgis-projects/webdav/test/test_upload.txt !tests/qgis-projects/ProJets 1982*! tests/qgis-projects/tests/media +tests/qgis-projects/tests/*_attachments.zip tests/qgis-server-plugins/* !tests/qgis-server-plugins/upgrade_projects.py tests/lizmap-qgis-plugin.master.zip diff --git a/tests/end2end/playwright/globals.js b/tests/end2end/playwright/globals.js index cb43a50e25..a799d8a7fd 100644 --- a/tests/end2end/playwright/globals.js +++ b/tests/end2end/playwright/globals.js @@ -1,25 +1,42 @@ // @ts-check const { expect } = require('@playwright/test'); -async function NoErrors(page) { +async function NoErrors(page, checkLayerTreeView = true) { // No error await expect(page.locator('p.error-msg')).toHaveCount(0); - await expect(page.locator('#switcher lizmap-treeview ul li')).not.toHaveCount(0); + if (checkLayerTreeView) { + await expect(page.locator('#switcher lizmap-treeview ul li')).not.toHaveCount(0); + } // Check no error message displayed await expect(page.getByText('An error occurred while loading this map. Some necessary resources may temporari')).toHaveCount(0); } -async function CatchErrors(page) { +/** + * CatchErrors function + * Some checks when the map is on error + * @param page The page object + * @param int layersInTreeView The number of layers to find in the treeview. + */ +async function CatchErrors(page, layersInTreeView = 0) { // Error await expect(page.locator('p.error-msg')).toHaveCount(1); - await expect(page.locator('#switcher lizmap-treeview ul li')).toHaveCount(0); + await expect(page.locator('#switcher lizmap-treeview ul li')).toHaveCount(layersInTreeView); // Error message displayed await expect(page.getByText('An error occurred while loading this map. Some necessary resources may temporari')).toBeVisible(); // Go back home link await expect(page.getByRole('link', { name: 'Go back to the home page.' })).toHaveCount(1); } -export async function gotoMap(url, page, check = true) { +/** + * gotoMap function + * Helper to load a map and do some basic checks + * @param string url The URL of the map to load + * @param page The page object + * @param boolean mapMustLoad If the loading of the map must be successful or not. Some error might be triggered when loading the map, on purpose. + * @param int layersInTreeView The number of layers to find in the treeview if the map is on error. + * @param boolean waitForGetLegendGraphics + */ +export async function gotoMap(url, page, mapMustLoad = true, layersInTreeView = 0, waitForGetLegendGraphics = true) { // TODO keep this function synchronized with the Cypress equivalent // Wait for WMS GetCapabilities promise @@ -28,19 +45,23 @@ export async function gotoMap(url, page, check = true) { // Wait for WMS GetCapabilities await getCapabilitiesWMSPromise; - if (check) { - // Wait for WMS GetLegendGraphic promise - const getLegendGraphicPromise = page.waitForRequest(request => request.method() === 'POST' && request.postData() != null && request.postData()?.includes('GetLegendGraphic') === true); - // Normal check about the map - // Wait for WMS GetLegendGraphic - await getLegendGraphicPromise; + if (mapMustLoad) { + if (waitForGetLegendGraphics) { + // Wait for WMS GetLegendGraphic promise + const getLegendGraphicPromise = page.waitForRequest(request => request.method() === 'POST' && request.postData() != null && request.postData()?.includes('GetLegendGraphic') === true); + // Normal check about the map + // Wait for WMS GetLegendGraphic + await getLegendGraphicPromise; + } // No error - await NoErrors(page); + await NoErrors(page, waitForGetLegendGraphics); // Wait to be sure the map is ready await page.waitForTimeout(1000) } else { + // Wait to be sure the map is ready + await page.waitForTimeout(1000) // Error - await CatchErrors(page); + await CatchErrors(page, layersInTreeView); } } diff --git a/tests/end2end/playwright/location_search.spec.js b/tests/end2end/playwright/location_search.spec.js new file mode 100644 index 0000000000..4614401dac --- /dev/null +++ b/tests/end2end/playwright/location_search.spec.js @@ -0,0 +1,106 @@ +// @ts-check +import { test, expect } from '@playwright/test'; +import { gotoMap } from './globals'; + +test.describe('Location search', () => { + + test('Default', async ({ page }) => { + const url = '/index.php/view/map?repository=testsrepository&project=location_search'; + await gotoMap(url, page, true, 0, false); + + await expect(page.getByPlaceholder('Search')).toHaveCount(1); + + await page.getByPlaceholder('Search').click(); + await page.getByPlaceholder('Search').fill('arceaux'); + + let ignPromise = page.waitForRequest(/data.geopf.fr/); + + await page.getByPlaceholder('Search').press('Enter'); + await ignPromise; + + await expect(page.getByText('IGN', { exact: true })).toHaveCount(1); + await expect(page.getByText('Map data', { exact: true })).toHaveCount(1); + + await page.getByPlaceholder('Search').click(); + await page.getByPlaceholder('Search').fill('mosson'); + + let searchPromise = page.waitForRequest(/searchFts/); + await page.getByPlaceholder('Search').press('Enter'); + await searchPromise; + + await expect(page.getByText('IGN', { exact: true })).toHaveCount(1); + await expect(page.getByText('Map data', { exact: true })).toHaveCount(0); + await expect(page.getByText('Quartier', { exact: true })).toHaveCount(1); + }); + + test('Only IGN', async ({ page }) => { + await page.route('**/service/getProjectConfig*', async route => { + const response = await route.fetch(); + const json = await response.json(); + json.options['searches'] = [ + { + "type": "externalSearch", + "service": "ign" + } + ]; + await route.fulfill({ response, json }); + }); + + const url = '/index.php/view/map?repository=testsrepository&project=location_search'; + await gotoMap(url, page, true, 0, false); + await expect(page.getByPlaceholder('Search')).toHaveCount(1); + + await page.getByPlaceholder('Search').click(); + await page.getByPlaceholder('Search').fill('arceaux'); + + let ignPromise = page.waitForRequest(/data.geopf.fr/); + + await page.getByPlaceholder('Search').press('Enter'); + await ignPromise; + + await expect(page.getByText('IGN', { exact: true })).toHaveCount(1); + await expect(page.getByText('Map data', { exact: true })).toHaveCount(0); + }); + + test('Only Fts', async ({ page }) => { + await page.route('**/service/getProjectConfig*', async route => { + const response = await route.fetch(); + const json = await response.json(); + json.options['searches'] = [ + { + "type": "Fts", + "service": "lizmapFts", + "url": "/index.php/lizmap/searchFts/get" + } + ]; + await route.fulfill({ response, json }); + }); + + const url = '/index.php/view/map?repository=testsrepository&project=location_search'; + await gotoMap(url, page, true, 0, false); + + await expect(page.getByPlaceholder('Search')).toHaveCount(1); + + await page.getByPlaceholder('Search').click(); + await page.getByPlaceholder('Search').fill('arceaux'); + + let searchPromise = page.waitForRequest(/searchFts/); + + await page.getByPlaceholder('Search').press('Enter'); + await searchPromise; + + await expect(page.getByText('IGN', { exact: true })).toHaveCount(0); + await expect(page.getByText('Map data', { exact: true })).toHaveCount(1); + + await page.getByPlaceholder('Search').click(); + await page.getByPlaceholder('Search').fill('mosson'); + + searchPromise = page.waitForRequest(/searchFts/); + await page.getByPlaceholder('Search').press('Enter'); + await searchPromise; + + await expect(page.getByText('Map data', { exact: true })).toHaveCount(0); + await expect(page.getByText('Quartier', { exact: true })).toHaveCount(1); + }); + +});