-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(web): Improve web e2e tests and move them to their directory #16842
base: main
Are you sure you want to change the base?
Changes from all commits
0f0c704
f626089
9ee7e96
05e489f
af54dcc
1226759
dc24b29
c3f0dbf
3e2cbf3
0d9addf
394c853
03cdcb7
b946139
0783e04
50b5a4d
d2393a5
a35543c
9251134
3e5405b
14c8be2
0964e55
1a4eea6
9cf35bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
version: '3' | ||
services: | ||
elasticsearch: | ||
image: docker.io/elasticsearch:8.8.0 | ||
ports: | ||
- 9200:9200 | ||
- 9300:9300 | ||
environment: | ||
- discovery.type=single-node | ||
- xpack.security.enabled=false | ||
healthcheck: | ||
test: ['CMD-SHELL', 'curl -f http://localhost:9200 || exit 1'] | ||
interval: 10s | ||
retries: 10 | ||
|
||
init-elasticsearch: | ||
image: docker.io/curlimages/curl:7.85.0 | ||
depends_on: | ||
elasticsearch: | ||
condition: service_healthy | ||
entrypoint: > | ||
sh -c " | ||
until curl -s http://elasticsearch:9200; do | ||
echo 'Waiting for Elasticsearch...'; | ||
sleep 5; | ||
done; | ||
curl -X PUT 'http://elasticsearch:9200/island-is-kstnl' -H 'Content-Type: application/json' -d' | ||
{ | ||
\"settings\": { | ||
\"number_of_shards\": 1, | ||
\"number_of_replicas\": 1 | ||
}, | ||
\"mappings\": { | ||
\"properties\": { | ||
\"title\": { | ||
\"type\": \"text\", | ||
\"fields\": { | ||
\"sort\": { | ||
\"type\": \"keyword\" | ||
} | ||
} | ||
}, | ||
\"dateUpdated\": { | ||
\"type\": \"date\" | ||
}, | ||
\"dateCreated\": { | ||
\"type\": \"date\" | ||
}, | ||
\"releaseDate\": { | ||
\"type\": \"date\" | ||
}, | ||
\"tags\": { | ||
\"type\": \"nested\", | ||
\"properties\": { | ||
\"key\": { | ||
\"type\": \"keyword\" | ||
}, | ||
\"type\": { | ||
\"type\": \"keyword\" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}'; | ||
" | ||
Comment on lines
+27
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve Elasticsearch index configuration and mappings The current index configuration could be enhanced:
Consider these improvements: - curl -X PUT 'http://elasticsearch:9200/island-is-kstnl' -H 'Content-Type: application/json' -d'
+ curl -X PUT 'http://elasticsearch:9200/web-content-v1' -H 'Content-Type: application/json' -d'
{
\"settings\": {
\"number_of_shards\": 1,
- \"number_of_replicas\": 1
+ \"number_of_replicas\": 0,
+ \"analysis\": {
+ \"analyzer\": {
+ \"custom_analyzer\": {
+ \"type\": \"custom\",
+ \"tokenizer\": \"standard\",
+ \"filter\": [
+ \"lowercase\",
+ \"asciifolding\"
+ ]
+ }
+ }
+ }
},
\"mappings\": {
\"properties\": {
\"title\": {
\"type\": \"text\",
+ \"analyzer\": \"custom_analyzer\",
\"fields\": {
\"sort\": {
\"type\": \"keyword\"
- }
+ },
+ \"suggest\": {
+ \"type\": \"completion\"
+ }
}
}, Also, consider adding validation rules for date fields and additional mapping properties for better search functionality.
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
import { | ||
type BrowserContext, | ||
createPageAndNavigate, | ||
expect, | ||
session, | ||
test, | ||
urls, | ||
} from '@island.is/testing/e2e' | ||
|
||
test.use({ baseURL: urls.islandisBaseUrl }) | ||
|
||
test.describe('Front page', { tag: '@fast' }, () => { | ||
let context: BrowserContext | ||
|
||
test.beforeAll(async ({ browser }) => { | ||
context = await session({ | ||
browser: browser, | ||
storageState: 'homepage.json', | ||
homeUrl: `${urls.islandisBaseUrl}/`, | ||
phoneNumber: '0103019', | ||
idsLoginOn: false, | ||
}) | ||
}) | ||
|
||
test.afterAll(async () => { | ||
await context.close() | ||
}) | ||
|
||
test('has expected sections @lang:is', async () => { | ||
const page = await createPageAndNavigate(context, '/') | ||
await expect( | ||
page.locator('text=Öll opinber þjónusta á einum stað'), | ||
).toBeVisible() | ||
await expect(page.locator('data-testid=home-banner')).toBeVisible() | ||
await expect(page.locator('data-testid=home-heading')).toBeVisible() | ||
await expect(page.locator('data-testid=home-news')).toBeVisible() | ||
}) | ||
|
||
test(`should have life event @lang:is`, async () => { | ||
test.slow() | ||
const page = await createPageAndNavigate(context, '/') | ||
const lifeEventsCards = page.locator('[data-testid="lifeevent-card"]') | ||
await expect(lifeEventsCards.count()).resolves.toBeGreaterThan(3) | ||
const lifeEventHandles = await lifeEventsCards.elementHandles() | ||
const lifeEventUrls = await Promise.all( | ||
lifeEventHandles.map((item) => item.getAttribute('href')), | ||
) | ||
const lifeEventPage = await context.newPage() | ||
for (const url of lifeEventUrls) { | ||
if (url) { | ||
const result = await lifeEventPage.goto(url ?? '') | ||
await expect( | ||
lifeEventPage.getByRole('link', { name: 'island.is logo' }), | ||
).toBeVisible() | ||
expect(result?.status()).toBe(200) | ||
} | ||
} | ||
await lifeEventPage.close() | ||
}) | ||
|
||
test(`should have life event @lang:en`, async () => { | ||
test.slow() | ||
const page = await createPageAndNavigate(context, '/en') | ||
const lifeEventsCards = page.locator('[data-testid="lifeevent-card"]') | ||
await expect(lifeEventsCards.count()).resolves.toBeGreaterThan(3) | ||
const lifeEventHandles = await lifeEventsCards.elementHandles() | ||
const lifeEventUrls = await Promise.all( | ||
lifeEventHandles.map((item) => item.getAttribute('href')), | ||
) | ||
const lifeEventPage = await context.newPage() | ||
for (const url of lifeEventUrls) { | ||
if (url) { | ||
const result = await lifeEventPage.goto(url ?? '') | ||
await expect( | ||
lifeEventPage.getByRole('link', { name: 'island.is logo' }), | ||
).toBeVisible() | ||
expect(result?.status()).toBe(200) | ||
} | ||
} | ||
await lifeEventPage.close() | ||
}) | ||
|
||
test(`should navigate to featured link @lang:is`, async () => { | ||
test.slow() | ||
const page = await createPageAndNavigate(context, '/') | ||
const featuredLinks = page.locator('[data-testid="featured-link"]') | ||
await expect(featuredLinks.count()).resolves.toBeGreaterThan(3) | ||
const featuredLinksHandles = await featuredLinks.elementHandles() | ||
const featuresLinksUrls = await Promise.all( | ||
featuredLinksHandles.map((item) => item.getAttribute('href')), | ||
) | ||
const featuredPage = await context.newPage() | ||
for (const url of featuresLinksUrls) { | ||
if (url) { | ||
const result = await featuredPage.goto(url) | ||
await expect( | ||
featuredPage.getByRole('link', { name: 'island.is logo' }), | ||
).toBeVisible() | ||
if (result) { | ||
expect(result.status()).toBe(200) | ||
} | ||
} | ||
} | ||
await featuredPage.close() | ||
}) | ||
|
||
test(`should navigate to featured link @lang:en`, async () => { | ||
test.slow() | ||
const page = await createPageAndNavigate(context, '/en') | ||
const featuredLinks = page.locator('[data-testid="featured-link"]') | ||
await expect(featuredLinks.count()).resolves.toBeGreaterThan(3) | ||
const featuredLinksHandles = await featuredLinks.elementHandles() | ||
const featuresLinksUrls = await Promise.all( | ||
featuredLinksHandles.map((item) => item.getAttribute('href')), | ||
) | ||
const featuredPage = await context.newPage() | ||
for (const url of featuresLinksUrls) { | ||
if (url) { | ||
const result = await featuredPage.goto(url) | ||
await expect( | ||
featuredPage.getByRole('link', { name: 'island.is logo' }), | ||
).toBeVisible() | ||
if (result) { | ||
expect(result.status()).toBe(200) | ||
} | ||
} | ||
} | ||
await featuredPage.close() | ||
}) | ||
|
||
test(`should have link on life events pages to navigate back to the main page @lang:is`, async () => { | ||
test.slow() | ||
const page = await createPageAndNavigate(context, '/') | ||
const lifeEventsCards = page.locator('[data-testid="lifeevent-card"]') | ||
const lifeEventHandles = await lifeEventsCards.elementHandles() | ||
const lifeEventUrls = await Promise.all( | ||
lifeEventHandles.map((item) => item.getAttribute('href')), | ||
) | ||
const lifeEventPage = await context.newPage() | ||
for (const url of lifeEventUrls) { | ||
if (url) { | ||
await lifeEventPage.goto(url) | ||
await lifeEventPage.locator('[data-testid="link-back-home"]').click() | ||
await expect( | ||
lifeEventPage.locator('data-testid=home-heading'), | ||
).toBeVisible() | ||
await expect(lifeEventPage).toHaveURL('/') | ||
} | ||
} | ||
await lifeEventPage.close() | ||
}) | ||
|
||
test(`should have link on life events pages to navigate back to the main page @lang:en`, async () => { | ||
test.slow() | ||
const page = await createPageAndNavigate(context, '/en') | ||
const lifeEventsCards = page.locator('[data-testid="lifeevent-card"]') | ||
const lifeEventHandles = await lifeEventsCards.elementHandles() | ||
const lifeEventUrls = await Promise.all( | ||
lifeEventHandles.map((item) => item.getAttribute('href')), | ||
) | ||
const lifeEventPage = await context.newPage() | ||
for (const url of lifeEventUrls) { | ||
if (url) { | ||
await lifeEventPage.goto(url) | ||
await lifeEventPage.locator('[data-testid="link-back-home"]').click() | ||
await lifeEventPage.locator('[data-testid="link-back-home"]').click() | ||
await expect( | ||
lifeEventPage.locator('data-testid=home-heading'), | ||
).toBeVisible() | ||
await expect(lifeEventPage).toHaveURL('/en') | ||
} | ||
} | ||
await lifeEventPage.close() | ||
}) | ||
|
||
test('should change welcome message on language toggle @lang:is', async () => { | ||
const page = await createPageAndNavigate(context, '/') | ||
const homeHeading = page.locator('h1[data-testid="home-heading"]') | ||
const icelandicHeading = await homeHeading.textContent() | ||
await page.locator('button[data-testid="language-toggler"]:visible').click() | ||
if (icelandicHeading) { | ||
await expect(homeHeading).not.toHaveText(icelandicHeading) | ||
} | ||
await expect(page).toHaveURL('/en') | ||
}) | ||
|
||
test('should toggle mega-menu @lang:is', async () => { | ||
const page = await createPageAndNavigate(context, '/') | ||
await page | ||
.locator('[data-testid="frontpage-burger-button"]:nth-child(2)') | ||
.click() | ||
await expect( | ||
page.locator('[data-testid="mega-menu-link"] > a').count(), | ||
).resolves.toBeGreaterThan(18) | ||
}) | ||
|
||
test('burger menu should open and close', async () => { | ||
const page = await createPageAndNavigate(context, '/') | ||
await page.getByRole('button', { name: 'Valmynd' }).click() | ||
|
||
await expect(page.getByRole('dialog', { name: 'Menu' })).toBeVisible() | ||
await expect(page.getByText('Þjónustuflokkar')).toBeVisible() | ||
await expect(page.getByRole('dialog', { name: 'Menu' })).toBeVisible() | ||
// Heading is "visible" behind menu | ||
// await expect(page.getByTestId('home-heading')).not.toBeVisible() | ||
await page | ||
.getByRole('dialog', { name: 'Menu' }) | ||
.getByRole('button') | ||
.getByTestId('icon-close') | ||
.click() | ||
await expect(page.getByTestId('home-heading')).toBeVisible() | ||
await expect(page.getByRole('dialog', { name: 'Menu' })).not.toBeVisible() | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { | ||
type BrowserContext, | ||
expect, | ||
session, | ||
test, | ||
urls, | ||
} from '@island.is/testing/e2e' | ||
|
||
test.use({ baseURL: urls.islandisBaseUrl }) | ||
|
||
test.describe('Search feature', { tag: '@fast' }, () => { | ||
let context: BrowserContext | ||
test.beforeAll(async ({ browser }) => { | ||
context = await session({ | ||
browser: browser, | ||
storageState: 'homepage.json', | ||
homeUrl: `${urls.islandisBaseUrl}/`, | ||
phoneNumber: '0103019', | ||
idsLoginOn: false, | ||
}) | ||
}) | ||
test.afterAll(async () => { | ||
await context.close() | ||
}) | ||
|
||
test('should display search results and navigate to result page', async () => { | ||
const testPhrase = 'umsókn' | ||
const page = await context.newPage() | ||
await page.goto('/', { waitUntil: 'networkidle' }) | ||
await page | ||
.getByRole('textbox', { name: 'Leitaðu á Ísland.is' }) | ||
.fill(testPhrase) | ||
await page.keyboard.press('Enter') | ||
const testResults = page.locator('[data-testid="search-result"]') | ||
await expect(testResults.count()).resolves.toBeGreaterThan(9) | ||
const searchUrl = page.url() | ||
await testResults.nth(0).click() | ||
await page.waitForLoadState('networkidle') | ||
await expect(page).not.toHaveURL(searchUrl) | ||
}) | ||
|
||
test('should have no search results for long bogus search words', async () => { | ||
const page = await context.newPage() | ||
await page.goto('/', { waitUntil: 'networkidle' }) | ||
await page | ||
.getByRole('textbox', { name: 'Leitaðu á Ísland.is' }) | ||
.fill('abcdefhijklmnopqrstuvwxyz1234567890') | ||
await page.keyboard.press('Enter') | ||
await page.waitForLoadState('networkidle') | ||
const testResults = page.locator('[data-testid="search-result"]') | ||
await expect(testResults).toHaveCount(0) | ||
}) | ||
svanaeinars marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
test.skip('should search in English', async () => { | ||
return | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security and configuration improvements needed for Elasticsearch service
Several important considerations for the Elasticsearch configuration:
Consider applying these improvements:
📝 Committable suggestion