Skip to content

Commit

Permalink
fix identity manager Visual tests and add to the list (#16)
Browse files Browse the repository at this point in the history
* fix identity manager Visual tests and add to the list

* add more screenshots

* wait for server ready when connecting to deployed app

* fix localization Visual tests and add to the list

* check that app is running before enabling features, and clean up

* fix quotes in NPM command when node is in .vaadin, improve logs

* add --cluster= parameter in order to run tests in any cluster

* set cluster context, and check https in installed apps

* fix kubectl port-forward in windows

* fix return when running playwrightTests in CC

* rename vars and check port 443

---------

Co-authored-by: edler-san <[email protected]>
  • Loading branch information
manolo and edler-san authored Feb 3, 2025
1 parent 6def259 commit d00b8e9
Show file tree
Hide file tree
Showing 10 changed files with 356 additions and 182 deletions.
73 changes: 57 additions & 16 deletions scripts/pit/its/cc-identity-management.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
const { expect} = require('@playwright/test');
const fs = require('fs');
const {log, args, createPage, closePage, takeScreenshot, waitForServerReady} = require('./test-utils');

const {log, err, args, createPage, closePage, takeScreenshot, waitForServerReady} = require('./test-utils');

(async () => {
const arg = args();
Expand All @@ -23,26 +21,39 @@ const {log, args, createPage, closePage, takeScreenshot, waitForServerReady} = r
await expect(page.getByLabel('Email')).toBeVisible();
await takeScreenshot(page, __filename, 'view-loaded');

log(`Logging in as ${arg.login} ${arg.pass}...\n`);
log(`Logging in CC as ${arg.login} ${arg.pass}...\n`);
await page.getByLabel('Email').fill(arg.login);
await page.getByLabel('Password').fill(arg.pass);
await page.getByRole('button', {name: 'Sign In'}).click()
await takeScreenshot(page, __filename, 'logged-in');

log(`Changing Settings for ${app}...\n`);
await page.getByRole('link', { name: 'Settings', }).click();
await takeScreenshot(page, __filename, 'settings');
const url = await page.locator(anchorSelectorURL).getAttribute('href');
log(`App: ${app} installed in: ${url}\n`);

log(`Checking that ${app} installed in ${url} is running ...\n`);

await page.locator('vaadin-select vaadin-input-container div').click();
await page.getByRole('option', { name: 'bakery-cc' }).locator('div').nth(2).click();
await page.getByRole('option', { name: app }).locator('div').nth(2).click();
await takeScreenshot(page, __filename, 'selected-app');

// When app is not running, localization button might not be enabled
let pageApp = await createPage(arg.headless, arg.ignoreHTTPSErrors);
await waitForServerReady(pageApp, url);
await takeScreenshot(pageApp, __filename, `app-${app}-running`);
await closePage(pageApp);
// Button is enabled after app is running, let's see
log(`Enabling identity Management ...\n`);
await page.getByRole('link', { name: 'Identity Management' }).click();
await takeScreenshot(page, __filename, 'identity-link-clicked');
await page.waitForTimeout(2000);
await page.getByRole('button', { name: 'Enable Identity Management' }).click();
await takeScreenshot(page, __filename, 'app-updated');
await takeScreenshot(page, __filename, 'enabled');
await takeScreenshot(page, __filename, 'identity-enabled');

log(`Adding Role, Group and User ...\n`);
await page.getByRole('link', { name: 'Roles' }).click();
await page.waitForTimeout(2000);
await page.getByRole('button', { name: 'Create' }).click();
await takeScreenshot(page, __filename, 'role-form');
await page.getByLabel('Name').fill(role);
Expand All @@ -52,6 +63,7 @@ const {log, args, createPage, closePage, takeScreenshot, waitForServerReady} = r
await takeScreenshot(page, __filename, 'role-created');

await page.getByRole('link', { name: 'Groups' }).click();
await page.waitForTimeout(2000);
await page.getByRole('button', { name: 'Create' }).click();
await takeScreenshot(page, __filename, 'group-form');
await page.getByLabel('Name').fill(group);
Expand All @@ -61,6 +73,7 @@ const {log, args, createPage, closePage, takeScreenshot, waitForServerReady} = r
await takeScreenshot(page, __filename, 'group-created');

await page.getByRole('link', { name: 'Users' }).click();
await page.waitForTimeout(2000);
await page.getByRole('button', { name: 'Create' }).click();
await takeScreenshot(page, __filename, 'user-form');
await page.getByLabel('First Name').fill(role);
Expand All @@ -72,15 +85,43 @@ const {log, args, createPage, closePage, takeScreenshot, waitForServerReady} = r
await page.getByRole('contentinfo').getByRole('button', { name: 'Create' }).click();
await takeScreenshot(page, __filename, 'user-created');

await waitForServerReady(page, url);
await takeScreenshot(page, __filename, `app-${app}-loaded`);

log(`Logging in ${app} as ${user} ...\n`);
await page.getByLabel('Email').fill(user);
await page.getByLabel('Password').fill(role);
await page.getByRole('button', {name: 'Sign In'}).click()
await takeScreenshot(page, __filename, `logged-in-${app}`);
await expect(page.getByRole('button', { name: 'New order' })).toBeVisible();
pageApp = await createPage(arg.headless, arg.ignoreHTTPSErrors);
await waitForServerReady(pageApp, url);
await takeScreenshot(pageApp, __filename, `app-${app}-loaded`);
await pageApp.getByLabel('Email').fill(user);
await pageApp.getByLabel('Password').fill(role);
await pageApp.getByRole('button', {name: 'Sign In'}).click()
await takeScreenshot(pageApp, __filename, `logged-in-${app}`);
await expect(pageApp.getByRole('button', { name: 'New order' })).toBeVisible();
await closePage(pageApp);

log('Cleaning up...\n');
try {
await page.getByRole('link', { name: 'Roles' }).click();
await page.waitForTimeout(2000);
await page.getByText(role, { exact: true }).nth(1).click();
await page.getByRole('button', { name: 'Delete' }).click();
await page.locator('vaadin-confirm-dialog-overlay').getByRole('button', { name: 'Delete' }).click();
await page.getByRole('link', { name: 'Groups' }).click();
await page.waitForTimeout(2000);
await page.getByText(group, { exact: true }).click();
await page.getByRole('button', { name: 'Delete' }).click();
await page.locator('vaadin-confirm-dialog-overlay').getByRole('button', { name: 'Delete' }).click();
await page.getByRole('link', { name: 'Users' }).click();
await page.waitForTimeout(2000);
await page.getByText(user, { exact: true }).click();
await page.getByRole('button', { name: 'Delete' }).click();
await page.locator('vaadin-confirm-dialog-overlay').getByRole('button', { name: 'Delete' }).click();
await page.getByRole('link', { name: 'Settings' }).click();
await page.waitForTimeout(2000);
await page.locator('vaadin-grid').getByText('bakery-cc', { exact: true }).click();
await page.getByLabel('Identity Management').uncheck();
await page.getByRole('button', { name: 'Disable' }).click();
await page.getByRole('button', { name: 'Update' }).click();
} catch (error) {
err(`Error cleaning up: ${error}\n`);
await takeScreenshot(page, __filename, 'error-cleaning');
}
await closePage(page);
})();
34 changes: 21 additions & 13 deletions scripts/pit/its/cc-install-apps.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { expect} = require('@playwright/test');
const fs = require('fs');
const {log, args, createPage, closePage, takeScreenshot, waitForServerReady} = require('./test-utils');
const {log, args, run, createPage, closePage, takeScreenshot, waitForServerReady} = require('./test-utils');

const arg = args();
let count = 0;
Expand All @@ -12,8 +12,6 @@ async function installApp(app, page) {
const cert = [ domain, uri ].map(a => `${a}.pem`).filter( a => fs.existsSync(a))[0]
console.log(`Installing App: ${app} URI: ${uri} Cert: ${cert}`);

await takeScreenshot(page, __filename, `page-loaded-${app}`);

await page.getByRole('listitem').filter({ hasText: 'Settings'}).click()
await page.getByRole('button', {name: 'Deploy'}).click()
await takeScreenshot(page, __filename, `form-opened-${app}`);
Expand All @@ -22,22 +20,26 @@ async function installApp(app, page) {
await page.getByLabel('Image', {exact: true}).fill(`k8sdemos/${app}:latest`)
await page.getByLabel('Application URI', {exact: true}).locator('input[type="text"]').fill(uri)
if (cert) {
log(`Uploading certificate ${cert} for ${app}...\n`);
await page.getByLabel('Upload').click();
const fileChooserPromise = page.waitForEvent('filechooser');
await page.getByText('Browse').click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(cert);
fileChooserPromise.then(await page.locator('.detail-layout').getByRole('button', {name: 'Deploy'}).click())
await takeScreenshot(page, __filename, `form-filled-${app}`);
await page.locator('.detail-layout').getByRole('button', {name: 'Deploy'}).click();
} else {
log(`No certificate found for ${app}...\n`);
log(`No certificate found for ${app}\n`);
run(`pwd`);
run(`ls -l`);
await page.getByLabel('Generate').click();
await takeScreenshot(page, __filename, `form-filled-${app}`);
await page.locator('.detail-layout').getByRole('button', {name: 'Deploy'}).click();
}

await takeScreenshot(page, __filename, `form-filled-${app}`);

await page.getByRole('listitem').filter({ hasText: 'Settings'}).click()

await takeScreenshot(page, __filename, `application-created-${app}`);
await takeScreenshot(page, __filename, `form-saved-${app}`);

await expect(page.locator('vaadin-grid').getByText(app, { exact: true })).toBeVisible();
await expect(await page.getByRole('listitem').filter({ hasText: 'Applications'})
Expand All @@ -64,13 +66,19 @@ async function installApp(app, page) {
await installApp(app, page);
}

log(`Waiting for the applications to be available...\n`);
log(`Waiting for 2 applications to be available...\n`);
const selector = 'vaadin-grid-cell-content span[theme="badge success"]';
await expect(page.locator(selector).nth(0)).toBeVisible({ timeout: 180000 });
const startTime = Date.now();

await expect(page.locator(selector).nth(0)).toBeVisible({ timeout: 280000 });
const firstAppTime = (Date.now() - startTime) / 1000;
await takeScreenshot(page, __filename, 'app-1-available');
log(`First application is available\n`);
await expect(page.locator(selector).nth(1)).toBeVisible({ timeout: 180000 });
log(`First application is available after ${firstAppTime.toFixed(2)} seconds\n`);

await expect(page.locator(selector).nth(1)).toBeVisible({ timeout: 280000 });
const secondAppTime = (Date.now() - startTime) / 1000;
await takeScreenshot(page, __filename, 'app-2-available');
log(`Second application is available\n`);
log(`Second application is available after ${secondAppTime.toFixed(2)} seconds\n`);

await closePage(page);
})();
175 changes: 110 additions & 65 deletions scripts/pit/its/cc-localization.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,119 @@
const {chromium} = require('playwright');
const sleep = ms => new Promise(r => setTimeout(r, ms));
const path = require('path');
const {expect} = require('@playwright/test');

const ADMIN_EMAIL = '[email protected]';
const ADMIN_PASSWORD = 'adminPassword';

let headless = false, host = 'localhost', port = '8000', hub = false;
process.argv.forEach(a => {
if (/^--headless/.test(a)) {
headless = true;
} else if (/^--ip=/.test(a)) {
ip = a.split('=')[1];
} else if (/^--port=/.test(a)) {
port = a.split('=')[1];
}
});
const { expect} = require('@playwright/test');
const fs = require('fs');
const {log, err, args, run, createPage, closePage, takeScreenshot, waitForServerReady} = require('./test-utils');
const { assert } = require('console');

(async () => {
const browser = await chromium.launch({
headless: headless,
chromiumSandbox: false
});
const context = await browser.newContext({ignoreHTTPSErrors: true});

// Open new page
const page = await context.newPage();
page.on('console', msg => console.log("> CONSOLE:", (msg.text() + ' - ' + msg.location().url).replace(/\s+/g, ' ')));
page.on('pageerror', err => console.log("> PAGEERROR:", ('' + err).replace(/\s+/g, ' ')));

// Go to http://${host}:${port}/
await page.goto(`http://${host}:${port}/`);

await page.getByLabel('Email').fill(ADMIN_EMAIL)
await page.getByLabel('Password', {exact: true}).fill(ADMIN_PASSWORD)
await page.getByRole('button', {name: 'Sign In'}).click()

await page.goto(`http://${host}:${port}/settings/apps/app1`);

const locOpt = page.getByLabel('Localization').click();
if(await !page.getByLabel('Localization').isChecked()){
await page.getByLabel('Localization').click({timeout:60000})
const arg = args();
if (!arg.login) {
log(`Skipping the setup of Control center because of missing --email= parameter\n`)
process.exit(1);
}
const app = `bakery-cc`;
const user = '[email protected]';
const password = 'admin';
const downloadsDir = './downloads';
const propsFile = 'translations.properties';

await page.getByRole('button', {name: 'Update'}).click()

await page.goto(`http://${host}:${port}/app/app1/i18n/translations`);

await page.getByRole('menuitem').click()
await page.getByText('Upload translations').click()
const page = await createPage(arg.headless, arg.ignoreHTTPSErrors);
await waitForServerReady(page, arg.url);

await expect(page.getByLabel('Email')).toBeVisible();
await takeScreenshot(page, __filename, 'view-loaded');

log(`Logging in CC as ${arg.login} ${arg.pass}...\n`);
await page.getByLabel('Email').fill(arg.login);
await page.getByLabel('Password').fill(arg.pass);
await page.getByRole('button', {name: 'Sign In'}).click()
await takeScreenshot(page, __filename, 'logged-in');

log(`Changing Settings for ${app}...\n`);
await page.getByRole('link', { name: 'Settings', }).click();
await takeScreenshot(page, __filename, 'settings');
const anchorSelectorURL = `//vaadin-grid-cell-content[.//span[normalize-space(text())="${app}"]]//a`;
const url = await page.locator(anchorSelectorURL).getAttribute('href');
const previewUrl = url.replace(/:\/\//, '://preview.');

log(`Checking that ${app} installed in ${url} is running ...\n`);
// When app is not running, localization cannot be enabled
const pageApp = await createPage(arg.headless, arg.ignoreHTTPSErrors);
await waitForServerReady(pageApp, url);
await takeScreenshot(pageApp, __filename, 'app-running');
await closePage(pageApp);

log(`Uploading and updating localization keys ...\n`);
await page.locator('vaadin-select vaadin-input-container div').click();
await page.getByRole('option', { name: app }).locator('div').nth(2).click();
await takeScreenshot(page, __filename, 'selected-app');

await page.getByRole('link', { name: 'Localization' }).click();
await page.getByRole('button', { name: 'Enable Localization' }).click();
await takeScreenshot(page, __filename, 'localization-enabled');

fs.writeFileSync(propsFile, 'app.title=Bakery\n');
await page.getByLabel('Manage translations').locator('svg').click();
await page.getByText('Upload translations').click();
await page.getByLabel('I understand that this will').check();
const fileChooserPromise = page.waitForEvent('filechooser');
await page.getByText('Upload Files...').click();
await page.getByRole('button', { name: 'Upload Files...' }).click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(path.join(__dirname, 'translations.properties'));
await page.getByLabel('I understand that this will replace all corresponding data.').check()
await page.getByRole('button', {name: 'Replace data'}).click()

await page.getByText('Hello anonymous!').click();
await page.locator('vaadin-grid-cell-content').getByRole('textbox').fill('Test');

await page.getByText('Say hello').click();
await page.locator('vaadin-grid-cell-content').getByRole('textbox').fill('Say bonjour');
await page.locator('.confirm-button').click();

expect(page.getByText('Hello anonymous!')).toBeVisible()
expect(page.locator('vaadin-grid-cell-content').filter({ hasText: 'Say bonjour' })).toBeVisible()

// ---------------------
await context.close();
await browser.close();
await fileChooser.setFiles(propsFile);
await page.getByRole('button', { name: 'Replace data' }).click();
fs.unlinkSync(propsFile);

await takeScreenshot(page, __filename, 'localization-loaded');
await page.getByText('Bakery', { exact: true }).click();
await page.locator('vaadin-text-area.inline textarea').fill('Panaderia');
await page.locator('vaadin-grid').getByRole('button').first().click();
await takeScreenshot(page, __filename, 'localization-changed');

log(`Downloading and checking localization keys ...\n`);
await page.getByLabel('Manage translations').locator('svg').click();
const downloadPromise = page.waitForEvent('download');
await page.getByText('Download translations').click();
const download = await downloadPromise;
const filePath = `${downloadsDir}/${download.suggestedFilename()}`;
await download.saveAs(filePath);

await run(`unzip -d ${downloadsDir} -o ${filePath}`);
const str = await fs.readFileSync('./downloads/translations.properties', 'utf8');
assert(str.includes('app.title=Panaderia'));
await fs.rmSync(downloadsDir, { recursive: true });

log(`Starting preview server\n`);
await page.getByRole('button', { name: 'Start preview' }).click();
await page.waitForTimeout(5000);

log(`Testing that preview page: ${previewUrl} is up and running\n`);
const pagePrev = await createPage(arg.headless, true /* preview pages do not have a valid certificate */);
await waitForServerReady(pagePrev, previewUrl);
await takeScreenshot(pagePrev, __filename, 'preview-ready');
const text = await pagePrev.getByText(/Password|Dashboard/).textContent();
if (text.includes('Password')) {
await pagePrev.getByLabel('Email').fill(user);
await pagePrev.getByLabel('Password').fill(password);
await pagePrev.getByRole('button', {name: 'Sign In'}).click()
await takeScreenshot(pagePrev, __filename, 'preview-logged-in');
await expect(pagePrev.getByRole('button', { name: 'New order' })).toBeVisible();
await takeScreenshot(pagePrev, __filename, 'preview-loaded');
}
// TODO: bakery is not internationalized
// await expect(pagePrev.getByText('Panaderia', { exact: true })).toBeVisible();
await closePage(pagePrev);

log('Cleaning up...\n');
try {
await page.getByRole('button', { name: 'Stop preview' }).click();
await page.getByRole('link', { name: 'Settings' }).click();
await page.waitForTimeout(2000);
await page.locator('vaadin-grid').getByText('bakery-cc', { exact: true }).click();
await page.waitForTimeout(2000);
await page.getByLabel('Localization').uncheck();
await page.getByRole('button', { name: 'Disable' }).click();
await page.getByRole('button', { name: 'Update' }).click();
} catch (error) {
err(`Error cleaning up: ${error}\n`);
await takeScreenshot(page, __filename, 'error-cleaning');
}
await closePage(page);
})();
4 changes: 2 additions & 2 deletions scripts/pit/its/cc-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ const {log, run, args, createPage, closePage, takeScreenshot, waitForServerReady

await takeScreenshot(page, __filename, 'password-changed');

await page.getByLabel('First Name').fill(arg.login);
await page.getByLabel('Last Name').fill(arg.login);
await page.getByLabel('First Name').fill(arg.login.split('@')[0]);
await page.getByLabel('Last Name').fill(arg.login.split('@')[1]);
await page.getByRole('button', { name: 'Submit' }).click();
await takeScreenshot(page, __filename, 'user-configured');

Expand Down
Loading

0 comments on commit d00b8e9

Please sign in to comment.