Skip to content
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

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions apps/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,43 @@ yarn nx extract-strings web

Currently, in this project, only the `Custom Page` content type utilizes the `Translation Namespace` content type for translations

## E2E Testing

### Quick Start

To run the E2E tests for the `web` app:

1. **Install dependencies** (if not already installed):

```bash
yarn install && yarn playwright install
```

2. **Run the tests**:

```bash
yarn e2e web
```

### Folder Structure

The `e2e` directory is organized as follows:

```shell
web/
└── e2e/
├── smoke/ # Smoke tests for basic functionality
└── acceptance/ # Acceptance tests for detailed workflows
```

### Mocking with Mockoon

Mock responses can be set up using Mockoon to simulate API behavior. Refer to the [Mockoon Usage Guide](../../libs/testing/e2e/README.md) for detailed instructions.

### More Resources

Refer to the [E2E Testing Library README](../../libs/testing/e2e/README.md) for common helper functions and utilities.
svanaeinars marked this conversation as resolved.
Show resolved Hide resolved

## Further Documentation

[Subpages](./docs/subpages.md) - Information on Layouts and Components used when
Expand Down
212 changes: 212 additions & 0 deletions apps/web/e2e/smoke/homepage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import {
type BrowserContext,
createPageAndNavigate,
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 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) {
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) {
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.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()
})
})
57 changes: 57 additions & 0 deletions apps/web/e2e/smoke/search.spec.ts
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', () => {
let context: BrowserContext
test.beforeAll(async ({ browser }) => {
context = await session({
browser: browser,
storageState: 'homepage.json',
homeUrl: `${urls.islandisBaseUrl}/`,
phoneNumber: '0103019',
idsLoginOn: false,
})
})
svanaeinars marked this conversation as resolved.
Show resolved Hide resolved
test.afterAll(async () => {
await context.close()
})

test('has expected sections', 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)
})

test.skip('should search in English', async () => {
return
})
})
Loading