Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 9 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ STRATEGIA_BASE_URL="https://helfi-strategia.docker.so"

# Other
PAATOKSET_BASE_URL="https://helsinki-paatokset.docker.so"
EMERGENCY_SITE_BASE_URL="https://emergency-site.docker.so"
EMERGENCY_SITE_STATIC_URL="https://poikkeustilanne.stage.hel.ninja"

# ============================================================================
# GLOBAL CONFIGURATION
Expand All @@ -38,3 +40,10 @@ PAATOKSET_BASE_URL="https://helsinki-paatokset.docker.so"

# CI mode
# CI=true

# Enable logger output.
# APP_DEBUG=TRUE

# Drupal admin user. Make sure this is an existing user in your target site.
# This needs to be a json encoded object with "username" and "password" keys.
# DRUPAL_E2E_USER='{"username": "drupal_e2e_user", "password": "drupal_e2e_password"}'
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,10 @@
"@xmldom/xmldom": "^0.8.11",
"ts-node": "^10.9.2",
"typescript": "^5.9.2"
},
"overrides": {
"ts-node": {
"diff": "^8.0.3"
}
}
}
5 changes: 5 additions & 0 deletions sites.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ export const sites: SiteConfig[] = [
envPrefix: 'ASUMINEN',
defaultBaseURL: 'https://www.test.hel.ninja',
},
{
name: 'emergency-site',
envPrefix: 'EMERGENCY_SITE',
defaultBaseURL: 'https://emergency-site.stage.hel.ninja',
},
// Add more sites here as needed:
// {
// name: 'asuminen',
Expand Down
66 changes: 66 additions & 0 deletions tests/sites/emergency-site/staticGeneration.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { expect, test } from '@playwright/test';
import { login, logout } from '../../../utils/authentication';
import { logger } from '../../../utils/logger';

test('Static generation test', async ({ page }) => {
// Timeout for the test. Azure purge process might take up to 45 minutes to
// finish, but content should be visible much sooner. So let's start with 15
// minutes.
const timeout = 15 * 60 * 1000;
test.setTimeout(timeout);

// Log in.
await login(page);

// Random string with a timestamp suffix.
const randomString = Math.random().toString(36).substring(2, 15) + Date.now().toString();

// Add new news item.
await page.goto('/en/node/add/news_item');
await page.locator('#edit-langcode-0-value').selectOption('en');
await page.locator('#edit-title-0-value').fill(`Test news ${randomString}`);
await page.locator('#edit-status-value').check();
await page.locator('#gin-sticky-edit-submit').click();

// Verify that the news item is created.
await expect(page.locator(`h1:has-text("Test news ${randomString}")`)).toBeVisible();

// Save announcement url for cleanup.
const announcementUrl = page.url();
logger(`Drupal news item URL: ${announcementUrl}`);

// Generate static news item URL.
const drupalUrlObject = new URL(announcementUrl);
const staticSiteUrl = process.env.EMERGENCY_SITE_STATIC_URL ?? 'https://poikkeustilanne.stage.hel.ninja';
const staticUrlObject = new URL(staticSiteUrl);
staticUrlObject.pathname = drupalUrlObject.pathname;
const staticNewsItemUrl = `${staticUrlObject.toString()}.html`;
logger(`Static news item URL: ${staticNewsItemUrl}`);

// Verify that news item is visible in static version. It might take
// up to 45 mins for the azure purge process to finish, but content should
// be visible much sooner.
const staticPage = await page.context().newPage();
await expect.poll(async () => {
const response = await staticPage.request.get(staticNewsItemUrl);
return response.status();
}, {
message: 'Make sure news item is eventually visible in static version.',
// Poll every 10 seconds.
intervals: [10 * 1000],
// Use the same timeout as the test.
timeout: timeout,
}).toBe(200);

// Remove test content.
await page.goto(announcementUrl);
await page.getByRole('link', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click();

// Verify test content no longer exists.
const response = await page.goto(announcementUrl);
expect(response?.status()).toBe(404);

// Log out.
await logout(page);
});
53 changes: 53 additions & 0 deletions utils/authentication.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { expect, type Page } from '@playwright/test';

/**
* Logs in to the site.
*
* @param page - Playwright Page object representing the browser page
*/
const login = async (page: Page) => {
// Get username and password from environment variable.
const user = process.env.DRUPAL_E2E_USER ?? null;
if (!user) {
throw new Error('DRUPAL_E2E_USER must be set');
}

let username = null;
let password = null;

try {
const userObject = JSON.parse(user);
username = userObject.username;
password = userObject.password;
} catch {
throw new Error('DRUPAL_E2E_USER must be a valid JSON object with "username" and "password" properties');
}

if (!username || !password) {
throw new Error('Username or password is not set.');
}

// Navigate to login page and submit login form.
await page.goto('/user/login');
await page.locator('#edit-name').fill(username);
await page.locator('#edit-pass').fill(password);
await page.locator('#edit-submit').click();

// Verify that the user is logged in.
await expect(page.locator('a[data-drupal-link-system-path="user/logout"]')).toBeAttached();
};

/**
* Logs out of the site.
*
* @param page - Playwright Page object representing the browser page
*/
const logout = async (page: Page) => {
await page.goto('/user/logout');
await page.locator('#edit-submit').click();

// Verify that the user is logged out.
await expect(page.locator('a[data-drupal-link-system-path="user/logout"]')).not.toBeAttached();
};

export { login, logout };