Ghost/ghost/core/test/e2e-browser/utils/e2e-browser-utils.js

138 lines
5.4 KiB
JavaScript
Raw Normal View History

const DataGenerator = require('../../utils/fixtures/data-generator');
/**
* Setup Ghost Admin, or login if there's a login prompt
* @param {import('@playwright/test').Page} page
*/
const setupGhost = async (page) => {
await page.goto('/ghost');
const actions = {
signin: Symbol(),
setup: Symbol(),
noAction: Symbol()
};
/**
* Using this to fix ESLint
* @type {object}
* @field {string} state
* @field {number} timeout
*/
const options = {
state: 'visible',
timeout: 10000
};
const action = await Promise.race([
page.locator('.gh-signin').waitFor(options).then(() => actions.signin).catch(() => {}),
page.locator('.gh-setup').waitFor(options).then(() => actions.setup).catch(() => {}),
page.locator('.gh-nav').waitFor(options).then(() => actions.noAction).catch(() => {})
]);
// TODO: Use env variables in CI
// Add owner user data from usual fixture
const ownerUser = DataGenerator.Content.users.find(user => user.id === '1');
if (action === actions.signin) {
// Fill email + password
await page.locator('#identification').fill(ownerUser.email);
await page.locator('#password').fill(ownerUser.password);
await page.locator('[data-test-button="sign-in"]').click();
// Confirm we have reached Ghost Admin
await page.locator('.gh-nav').waitFor(options);
} else if (action === actions.setup) {
// Complete setup process
await page.getByPlaceholder('The Daily Awesome').click();
await page.getByPlaceholder('The Daily Awesome').fill('The Local Test');
// Add owner user data from usual fixture
await page.getByPlaceholder('Jamie Larson').fill(ownerUser.name);
await page.getByPlaceholder('jamie@example.com').fill(ownerUser.email);
await page.getByPlaceholder('At least 10 characters').fill(ownerUser.password);
await page.getByPlaceholder('At least 10 characters').press('Enter');
await page.locator('.gh-done-pink').click();
await page.locator('.gh-nav').waitFor(options);
}
};
let isStripeSetup = false;
/**
* Connect from Stripe using the UI, disconnecting if necessary
* @param {import('@playwright/test').Page} page
*/
const setupStripe = async (page) => {
if (isStripeSetup) {
return;
}
await page.goto('/ghost');
await page.locator('[data-test-nav="settings"]').click();
await page.locator('[data-test-nav="members-membership"]').click();
if (await page.isVisible('.gh-btn-stripe-status.connected')) {
// Disconnect if already connected
await page.locator('.gh-btn-stripe-status.connected').click();
await page.locator('.modal-content .gh-btn-stripe-disconnect').first().click();
// TODO: Use a better selector to achieve this
await page
.locator('.modal-content')
.filter({hasText: 'Are you sure you want to disconnect?'})
.first()
.getByRole('button', {name: 'Disconnect'})
.click();
} else {
await page.locator('.gh-setting-members-tierscontainer .stripe-connect').click();
}
await page.locator('input[data-test-checkbox="stripe-connect-test-mode"]').first().check();
const [stripePage] = await Promise.all([
page.waitForEvent('popup'),
page.getByRole('link', {name: 'Connect with Stripe'}).click()
]);
await stripePage.locator('#skip-account-app').click();
const stripeKey = await stripePage.locator('code').innerText();
await stripePage.close();
await page.getByPlaceholder('Paste your secure key here').fill(stripeKey);
await page.getByRole('button', {name: 'Save Stripe settings'}).click();
await page.locator('[data-test-button="stripe-connect-ok"]').click();
isStripeSetup = true;
};
/**
* Connect from Stripe using the UI, disconnecting if necessary
* @param {import('@playwright/test').Page} page
* @param {object} tier
* @param {string} tier.name
* @param {number} tier.monthlyPrice
* @param {number} tier.yearlyPrice
*/
const createTier = async (page, {name, monthlyPrice, yearlyPrice}) => {
await page.locator('[data-test-nav="settings"]').click();
await page.locator('[data-test-nav="members-membership"]').click();
// Expand the premium tier list
await page.getByRole('button', {name: 'Expand'}).nth(1).click({
delay: 10 // Wait 10 milliseconds to ensure tier information appears correctly
});
// Archive if already exists
if (await page.locator('.gh-tier-card-name').getByText(name).isVisible()) {
const tierCard = page.locator('.gh-tier-card').filter({hasText: name}).first();
await tierCard.locator('.gh-tier-card-actions-button').click();
await tierCard.getByRole('button', {name: 'Archive'}).click();
await page.locator('.modal-content').getByRole('button', {name: 'Archive'}).click();
}
await page.locator('.gh-btn-add-tier').click();
await page.locator('input[data-test-input="tier-name"]').first().fill(name);
await page.locator('#monthlyPrice').fill(`${monthlyPrice}`);
await page.locator('#yearlyPrice').fill(`${yearlyPrice}`);
await page.locator('[data-test-button="save-tier"]').click();
await page.waitForSelector('input[data-test-input="tier-name"]', {state: 'detached'});
};
module.exports = {
setupGhost,
setupStripe,
createTier
};