Skip to content

feat: more versatile options for the control-center #25

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

Merged
merged 5 commits into from
Jun 6, 2025
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
69 changes: 69 additions & 0 deletions CC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

## Usage examples for PiT tests in control-center

##### Run proxy
./scripts/pit/run.sh --proxy

##### Delete cluster in DO
./scripts/pit/run.sh --proxy --delete --vendor=do

##### Install cluster and helm chart for a specific CC version
./scripts/pit/run.sh --starters=control-center --keep-cc \
--cc-version=1.3.0-beta2 \
--skip-pw

##### Compile apps and CC for a specific platform version, and load local images in cluster
./scripts/pit/run.sh --starters=control-center --keep-cc \
--version=24.8.0.beta2 \
--skip-current \
--skip-helm \
--skip-pw

##### Push local images to docker central (need to be build as above)
CCPUSH=true \
./scripts/pit/run.sh --starters=control-center --keep-cc \
--version=24.8.0.beta2 \
--skip-current \
--skip-build \
--skip-helm \
--skip-pw

./scripts/pit/run.sh --function pushLocalToDockerhub next

##### Install test apps and run tests for new version (needs to have everything set as above)
./scripts/pit/run.sh --starters=control-center --keep-cc \
--version=24.8.0.beta2 \
--skip-current \
--skip-build \
--skip-helm \
--keep-apps \
--headed

##### Run browser tests without headed slow-motion
FAST=true \
./scripts/pit/run.sh --starters=control-center --keep-cc \
--version=24.8.0.beta2 \
--skip-current \
--skip-build \
--skip-helm \
--keep-apps \
--headed

##### Remove tests apps from CC
CC_TESTS=cc-remove-apps.js \
./scripts/pit/run.sh --starters=control-center --keep-cc \
--offline \
--skip-setup \
--headed

##### Create a cluster in DO with latest version of CC, compile apps and deploy then
FAST=true ./scripts/pit/run.sh \
--starters=control-center --keep-cc --version=24.8.0.beta2 --headed --skip-current --vendor=do








18 changes: 4 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
# [Platform-In-Test Script]

# How To Use

```
./scripts/pit/run.sh --help
```

```
Use: ./scripts/pit/run.sh with the next options:

--version=string Vaadin version to test, if not given it only tests current stable, otherwise it runs tests against current stable and then against given version.
Expand All @@ -23,13 +14,15 @@ Use: ./scripts/pit/run.sh with the next options:
--skip-prod Skip production validations
--skip-dev Skip dev-mode validations
--skip-clean Do not clean maven cache
--skip-helm Do not re-install control-center with helm and continue running tests, implies (--offline, --skip-build, --keep-cc)
--skip-helm Do not re-install control-center with helm and continue running tests, implies (--offline, --keep-cc)
--skip-pw Do not run playwright tests
--cluster=name Run tests in an existing k8s cluster
--vendor=name Use a specific cluster vendor to run control-center tests options: [dd, kind, do] (default: kind)
--keep-cc Keep control-center running after tests
--keep-apps Keep installed apps in control-center, implies --keep-cc
--proxy-cc Forward port 443 from k8s cluster to localhost
--events-cc Display events from control-center
--cc-version Install this version for current
--skip-build Skip building the docker images for control-center
--delete-cluster Delete the cluster/s
--dashboard=* Install kubernetes dashboard, options [install, uninstall] (default: install)
Expand Down Expand Up @@ -113,7 +106,4 @@ Use: ./scripts/pit/run.sh with the next options:
· designer-tutorial
· walking-skeleton:v24.7-hybrid
· releases-graph
```



· expo-flow
5 changes: 3 additions & 2 deletions scripts/pit/its/cc-identity-management.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ const {log, err, args, createPage, closePage, takeScreenshot, waitForServerReady
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 {
Expand Down Expand Up @@ -142,13 +143,13 @@ const {log, err, args, createPage, closePage, takeScreenshot, waitForServerReady
await page.getByLabel('Replicas').fill('1');
await page.getByRole('button', { name: 'Update' }).click();

await pageApp.waitForTimeout(30000);
pageApp = await createPage(arg.headless, arg.ignoreHTTPSErrors);
await waitForServerReady(pageApp, appUrl);
await takeScreenshot(pageApp, __filename, 'app-after-cleanup');
} catch (error) {
err(`Error cleaning up: ${error}\n`);
await takeScreenshot(page, __filename, 'error-cleaning');
}
await closePage(pageApp);
await closePage(page);
await closePage(pageApp);
})();
47 changes: 30 additions & 17 deletions scripts/pit/its/cc-install-apps.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const { expect} = require('@playwright/test');
const fs = require('fs');
const {log, err, args, run, createPage, closePage, takeScreenshot, waitForServerReady} = require('./test-utils');
const {log, args, run, createPage, closePage, takeScreenshot, waitForServerReady} = require('./test-utils');

const arg = args();
let count = 0;
const gracePeriodSecs = 90;
const waitForReadyMsecs = 185000;

async function installApp(app, page) {
const host = arg.url.replace(/^.*:\/\//, '').replace(/\/.*$/, '');
Expand All @@ -12,7 +14,7 @@ async function installApp(app, page) {
const cert = [ domain, uri ].map(a => `${a}.pem`).filter( a => fs.existsSync(a))[0]
const tag = arg.tag || 'latest';
const registry = arg.registry || 'k8sdemos';
console.log(`Installing App: ${app} URI: ${uri} Cert: ${cert}`);
log(`Installing App: ${app} URI: ${uri} Cert: ${cert} Img: ${registry}/${app}:${tag}`);

await page.getByRole('listitem').filter({ hasText: 'Settings'}).click()
await page.getByRole('button', {name: /Create|New/}).click()
Expand All @@ -25,8 +27,20 @@ async function installApp(app, page) {
await page.getByPlaceholder('Image Pull Secret').locator('input').fill(arg.secret);
await takeScreenshot(page, __filename, `form-with-secret-${app}`);
}
await page.getByLabel('Startup Delay (secs)').fill(process.env.GITHUB_ACTIONS ? '90' : '90');
await page.getByLabel('Startup Delay (secs)').fill(`${gracePeriodSecs}`);

await page.getByRole('button', {name: 'Environment Variable'}).click();
await takeScreenshot(page, __filename, `env-dialog-opened-${app}`);

const envDialog = page.getByRole('dialog', { name: 'Environment Variables' });
await envDialog.getByPlaceholder('Name').locator('input').fill('SPRING_FLYWAY_ENABLED');
await envDialog.getByPlaceholder('Value').locator('input').fill('false');
await envDialog.getByLabel("Add").click();
await takeScreenshot(page, __filename, `env-dialog-filled-${app}`);
await envDialog.getByLabel("Close").click();

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();
Expand All @@ -37,7 +51,6 @@ async function installApp(app, page) {
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`);
Expand Down Expand Up @@ -70,27 +83,27 @@ async function installApp(app, page) {
await page.getByRole('button', {name: 'Sign In'}).click()
await takeScreenshot(page, __filename, 'logged-in');

for (const app of ['bakery-cc', 'bakery']) {
const apps = ['cc-starter', 'bakery-cc', 'bakery'];
for (const app of apps) {
await installApp(app, page);
}

await takeScreenshot(page, __filename, 'installed-apps');
const startTime = Date.now();
log(`Giving a grace period of 40 secs to wait for 2 apps to be avalable ...\n`);
await page.waitForTimeout(40000);
log(`Giving a grace period of ${gracePeriodSecs} secs to wait for ${apps.length} apps to be avalable ...\n`);
await page.waitForTimeout(gracePeriodSecs);
await page.reload();
log(`Waiting for 2 applications to be available in dashboard ...\n`);
log(`Waiting for ${apps.length} applications to be available in dashboard ...\n`);
await takeScreenshot(page, __filename, 'waiting for apps');

const selector = 'vaadin-grid-cell-content span[theme="badge success"]';
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 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 after ${secondAppTime.toFixed(2)} seconds\n`);

for (let i = 0; i < apps.length; i++) {
await expect(page.locator(selector).nth(i)).toBeVisible({ timeout: waitForReadyMsecs });
const firstAppTime = (Date.now() - startTime) / 1000;
await takeScreenshot(page, __filename, 'app-1-available');
log(`application ${i + 1} is available after ${firstAppTime.toFixed(2)} seconds\n`);
}

await closePage(page);
})();
55 changes: 55 additions & 0 deletions scripts/pit/its/cc-remove-apps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const {log, args, createPage, closePage, takeScreenshot, waitForServerReady} = require('./test-utils');

const arg = args();

async function remove(app, page) {
log(`Removing ${app}...\n`);
await page.getByRole('link', { name: 'Settings', }).click();
await takeScreenshot(page, __filename, 'settings');

const anchorSelector = `//vaadin-grid-cell-content[.//span[normalize-space(text())="${app}"]]`;
const anchors = page.locator(anchorSelector);
const c = await anchors.count();
if (c <= 0) {
log(`App ${app} not found`);
return;
}
if (c == 1) {
const text = await anchors.nth(0).textContent();
log(`Found one element ${text}`);
}
if (c > 1) {
log(`App ${app} link found multiple times`);
for (let i = 0; i < c; i++) {
const text = await anchors.nth(i).textContent();
log(`Element ${i}: ${text}`);
}
}
await anchors.nth(0).click();

await page.getByRole('button', { name: 'Delete' }).click();
await page.getByLabel('I understand that this will').check();
await page.getByRole('button', { name: 'Delete' }).click();
}

(async () => {
if (!arg.login) {
log(`Skipping the setup of Control center because of missing --email= parameter\n`)
process.exit(1);
}
const page = await createPage(arg.headless, arg.ignoreHTTPSErrors);
await waitForServerReady(page, arg.url);
await takeScreenshot(page, __filename, 'view-loaded');

log(`Logging in 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');

for (const app of ['bakery-cc', 'bakery', 'cc-starter']) {
await remove(app, page);
}

await closePage(page);
})();
37 changes: 22 additions & 15 deletions scripts/pit/its/cc-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,29 @@ const {log, run, args, createPage, closePage, takeScreenshot, waitForServerReady

await takeScreenshot(page, __filename, 'logged-in');

await page.getByLabel('New Password').fill(arg.pass);
await page.getByLabel('Confirm Password').fill(arg.pass);
await page.getByRole('button', { name: 'Submit' }).click();

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

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');

await waitForServerReady(page, arg.url);
const newsPass = page.getByLabel('New Password');
if (await newsPass.count() == 0) {
log("Seems that CC was already setup trying to login")
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');
} else {
await newsPass.fill(arg.pass);
await page.getByLabel('Confirm Password').fill(arg.pass);
await page.getByRole('button', { name: 'Submit' }).click();

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

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');
await waitForServerReady(page, arg.url);
await page.getByRole('button', { name: 'Manage applications' }).click();
}

await page.getByRole('button', { name: 'Manage applications' }).click();
await page.getByRole('listitem').filter({ hasText: 'Settings'}).click()
await expect(page.getByRole('heading', { name: 'Applications' })).toBeVisible();
await page.waitForTimeout(5000);

await closePage(page);
})();
2 changes: 1 addition & 1 deletion scripts/pit/its/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ async function createPage(headless, ignoreHTTPSErrors) {
const browser = await chromium.launch({
headless: headless,
chromiumSandbox: false,
slowMo: headless ? 400: 1000,
slowMo: process.env.FAST ? 0 : headless ? 400: 1000,
args: ['--window-position=0,0']
});
const context = await browser.newContext({ignoreHTTPSErrors: ignoreHTTPSErrors, viewport: { width: 1792, height: 970 } });
Expand Down
Loading