Skip to content

Commit

Permalink
feat: Move web e2e tests to web app directory
Browse files Browse the repository at this point in the history
  • Loading branch information
svanaeinars committed Nov 13, 2024
1 parent af03eb5 commit 0f0c704
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 0 deletions.
146 changes: 146 additions & 0 deletions apps/web/e2e/smoke/homepage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import {
BrowserContext,
expect,
session,
test,
urls,
} from '@island.is/testing/e2e'

test.use({ baseURL: urls.islandisBaseUrl })

test.describe('Front page', () => {
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 context.newPage()
await page.goto('/')
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()
})

for (const { lang, home } of [
{ lang: 'is', home: '/' },
{ lang: 'en', home: '/en' },
]) {
test(`should have life event @lang:${lang}`, async () => {
test.slow()
const page = await context.newPage()
await page.goto(home)
const lifeEventsCards = page.locator('[data-testid="lifeevent-card"]')

await expect(lifeEventsCards).toHaveCountGreaterThan(3)
const lifeEventHandles = await lifeEventsCards.elementHandles()
const lifeEventUrls = await Promise.all(
lifeEventHandles.map((item) => item.getAttribute('href')),
)
for (const url of lifeEventUrls) {
const page = await context.newPage()
const result = await page.goto(url!)
await expect(
page.getByRole('link', { name: 'island.is logo' }),
).toBeVisible()
expect(result!.status()).toBe(200)
await page.close()
}
})
test(`should navigate to featured link @lang:${lang}`, async () => {
test.slow()
const page = await context.newPage()
await page.goto(home)
const featuredLinks = page.locator('[data-testid="featured-link"]')
await expect(featuredLinks).toHaveCountGreaterThan(3)
const featuredLinksHandles = await featuredLinks.elementHandles()
const featuresLinksUrls = await Promise.all(
featuredLinksHandles.map((item) => item.getAttribute('href')),
)
for (const url of featuresLinksUrls) {
const page = await context.newPage()
const result = await page.goto(url!)
await expect(
page.getByRole('link', { name: 'island.is logo' }),
).toBeVisible()
expect(result!.status()).toBe(200)
await page.close()
}
})

test(`should have link on life events pages to navigate back to the main page @lang:${lang}`, async () => {
test.slow()
const page = await context.newPage()
await page.goto(home)
const lifeEventsCards = page.locator('[data-testid="lifeevent-card"]')
const lifeEventHandles = await lifeEventsCards.elementHandles()
const lifeEventUrls = await Promise.all(
lifeEventHandles.map((item) => item.getAttribute('href')),
)
for (const url of lifeEventUrls) {
const page = await context.newPage()
const result = await page.goto(url!)
expect(result?.url()).not.toBe(home)
await page.locator('[data-testid="link-back-home"]').click()
await expect(page.locator('data-testid=home-heading')).toBeVisible()
await expect(page).toHaveURL(home)
await page.close()
}
})
}

test('should change welcome message on language toggle @lang:is', async () => {
const page = await context.newPage()
await page.goto('/')
const homeHeading = page.locator('h1[data-testid="home-heading"]')
const icelandicHeading = await homeHeading.textContent()
await page.locator('button[data-testid="language-toggler"]:visible').click()
await expect(homeHeading).not.toHaveText(icelandicHeading!)
await expect(page).toHaveURL('/en')
})

test('should toggle mega-menu @lang:is', async () => {
const page = await context.newPage()
await page.goto('/')
await page
.locator('[data-testid="frontpage-burger-button"]:nth-child(2)')
.click()
await expect(
page.locator('[data-testid="mega-menu-link"] > a'),
).toHaveCountGreaterThan(18)
})

test('burger menu should open and close', async () => {
// Arrange
const page = await context.newPage()
page.goto('/')
await page.getByRole('button', { name: 'Valmynd' }).click()

// Act
await expect(page.getByRole('dialog', { name: 'Menu' })).toBeVisible()
await expect(
page.getByRole('paragraph').filter({ hasText: 'Þ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()
})
})
58 changes: 58 additions & 0 deletions apps/web/e2e/smoke/search.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {
BrowserContext,
expect,
session,
test,
urls,
} from '@island.is/testing/e2e'

test.use({ baseURL: urls.islandisBaseUrl })

test.describe('Search feature', () => {
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', async () => {
const testPhrase = 'umsókn'
const page = await context.newPage()
await page.goto('/')
await page
.getByRole('textbox', { name: 'Leitaðu á Ísland.is' })
.type(testPhrase, { delay: 100 })
await page.keyboard.press('Enter')
const testResults = page.locator('[data-testid="search-result"]')
await expect(testResults).toHaveCountGreaterThan(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('/')
await page.type(
'role=textbox[name="Leitaðu á Ísland.is"]',
'abcdefhijklmnopqrstuvwxyz1234567890',
)
await page.keyboard.press('Enter')
await page.waitForLoadState('networkidle')
const testResults = page.locator('[data-testid="search-result"]')
await expect(testResults).toHaveCount(0)
})

test.skip('should search in Enlish', async () => {
return
})
})
80 changes: 80 additions & 0 deletions apps/web/e2e/smoke/sites-of-institutions.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import slugify from 'slugify'

import {
BrowserContext,
expect,
Page,
session,
test,
urls,
} from '@island.is/testing/e2e'

type GetByRole = Pick<Page, 'getByRole'>['getByRole']
type GetByRoleParameters = Parameters<GetByRole>

test.use({ baseURL: urls.islandisBaseUrl })
type Orgs = {
organisationName: string
organisationHome?: string
enabled?: boolean
target?: { role: GetByRoleParameters[0]; options?: GetByRoleParameters[1] }
}
const orgs: Orgs[] = [
{ organisationName: 'Opinberir aðilar', organisationHome: '/' },
{ organisationName: 'Fiskistofa' },
{
organisationName: 'Heilbrigðisstofnun Norðurlands',
organisationHome: '/hsn',
},
{ organisationName: 'Sjúkratryggingar', target: { role: 'link' } },
{ organisationName: 'Ríkislögmaður' },
{ organisationName: 'Landskjörstjórn', target: { role: 'link' } },
{ organisationName: 'Opinber nýsköpun', enabled: true },
{ organisationName: 'Sýslumenn' },
{ organisationName: 'Fjársýslan' },
{
organisationName: 'Heilbrigðisstofnun Suðurlands',
organisationHome: '/hsu',
},
{
organisationName: 'Landlæknir',
target: { role: 'link', options: { name: 'Eyðublöð' } },
},
{ organisationName: 'Útlendingastofnun', target: { role: 'link' } },
]

test.describe('Sites of institutions', () => {
let context: BrowserContext
test.beforeAll(async ({ browser }) => {
context = await session({
browser,
idsLoginOn: false,
homeUrl: '/s',
})
})
test.afterAll(async () => {
await context.close()
})
for (const {
organisationName,
organisationHome = `/${slugify(organisationName, { lower: true })}`,
target,
enabled,
} of orgs) {
test(organisationName, async () => {
if (enabled) return
const page = await context.newPage()
const url = `/s${organisationHome}`
await page.goto(url)
await expect(
page
.getByRole(target?.role ?? 'heading', {
...{ name: organisationName },
...target?.options,
})
.first(),
).toBeVisible()
await page.close()
})
}
})
40 changes: 40 additions & 0 deletions apps/web/e2e/utils/addons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { expect, Locator, Page, sleep } from '@island.is/testing/e2e'

expect.extend({
async toHaveCountGreaterThan(
received: Locator,
value: number,
options: { timeout: number; sleepTime: number } = {
timeout: 10000,
sleepTime: 100,
},
) {
const initialTime = Date.now()
let count = -1
while (count <= value) {
count = await received.count()
if (Date.now() > initialTime + options.timeout)
return { message: () => 'Timeout', pass: false }
await sleep(options.sleepTime)
}
return {
message: () => `Found ${count} elements`,
pass: true,
}
},
async toBeApplication(received: string | Page, applicationType = '\\w+') {
const url: string = typeof received == 'string' ? received : received.url()
const protocol = 'https?://'
const host = '[^/]+'
const applicationId = '(/(\\w|-)*)?'
const applicationRegExp = new RegExp(
`^${protocol}${host}/umsoknir/${applicationType}${applicationId}$`,
)
const pass = applicationRegExp.test(url)
const message = () =>
`Current page is ${pass ? '' : '*not* '}an application
Pattern ${applicationRegExp}
URL is ${url}`
return { message, pass }
},
})
11 changes: 11 additions & 0 deletions apps/web/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createPlaywrightConfig } from '@island.is/testing/e2e'

import './e2e/utils/addons'

const webConfig = createPlaywrightConfig({
webServerUrl: 'http://localhost:4200',
command: 'yarn dev-init web && source .env.secret && yarn dev web',
cwd: '../../',
})

export default webConfig
6 changes: 6 additions & 0 deletions apps/web/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@
},
"docker-next": {
"executor": "Intentionally left blank, only so this target is valid when using `nx show projects --with-target docker-next`"
},
"e2e": {
"executor": "@nx/playwright:playwright",
"options": {
"config": "{projectRoot}/playwright.config.ts"
}
}
}
}

0 comments on commit 0f0c704

Please sign in to comment.