Skip to content
Open
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
4 changes: 2 additions & 2 deletions zeppelin-web-angular/.gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.

# compiled output
/dist
**/dist
/tmp
/out-tsc

# dependencies
/node_modules
**/node_modules

# profiling files
chrome-profiler-events.json
Expand Down
24 changes: 17 additions & 7 deletions zeppelin-web-angular/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,16 @@
},
"architect": {
"build": {
"builder": "ngx-build-plus:browser",
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"outputPath": "dist/zeppelin",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.json",
"customWebpackConfig": {
"path": "./webpack.config.js"
},
"assets": [
"src/favicon.ico",
"src/assets",
Expand All @@ -62,6 +65,11 @@
"glob": "**/*",
"input": "./WEB-INF",
"output": "/WEB-INF/"
},
{
"glob": "**/*",
"input": "./projects/zeppelin-react/dist",
"output": "/assets/react/"
}
],
"styles": [
Expand Down Expand Up @@ -100,27 +108,29 @@
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": false
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"namedChunks": true,
"sourceMap": true
}
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "ngx-build-plus:dev-server",
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"browserTarget": "zeppelin:build"
"browserTarget": "zeppelin:build",
"port": 4200,
"host": "localhost",
"liveReload": true,
"hmr": true
},
"configurations": {
"production": {
Expand Down
6 changes: 4 additions & 2 deletions zeppelin-web-angular/e2e/models/home-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ export class HomePage extends BasePage {
}

async navigateToHome(): Promise<void> {
await this.page.goto('/', { waitUntil: 'load' });
await this.page.goto('/');
await this.waitForPageLoad();
}

async navigateToLogin(): Promise<void> {
await this.page.goto('/#/login', { waitUntil: 'load' });
await this.page.goto('/#/login');
await this.waitForPageLoad();
// Wait for potential redirect to complete by checking URL change
await waitForUrlNotContaining(this.page, '#/login');
Expand Down Expand Up @@ -189,6 +189,8 @@ export class HomePage extends BasePage {
}

async filterNotes(searchTerm: string): Promise<void> {
await this.page.waitForLoadState('domcontentloaded', { timeout: 10000 });
await this.nodeList.filterInput.waitFor({ state: 'visible', timeout: 5000 });
await this.nodeList.filterInput.fill(searchTerm);
}

Expand Down
24 changes: 9 additions & 15 deletions zeppelin-web-angular/e2e/models/home-page.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export class HomePageUtil {
await expect(this.homePage.notebookList).toBeVisible();

// Additional wait for content to load
await this.page.waitForTimeout(1000);
await this.page.waitForLoadState('networkidle', { timeout: 15000 });
}

async verifyNotebookRefreshFunctionality(): Promise<void> {
Expand Down Expand Up @@ -183,31 +183,25 @@ export class HomePageUtil {
async verifyCreateNewNoteWorkflow(): Promise<void> {
await this.homePage.clickCreateNewNote();

await this.page.waitForFunction(
() => {
return document.querySelector('zeppelin-note-create') !== null;
},
{ timeout: 10000 }
);
await this.page.waitForFunction(() => document.querySelector('zeppelin-note-create') !== null, { timeout: 10000 });
}

async verifyImportNoteWorkflow(): Promise<void> {
await this.homePage.clickImportNote();

await this.page.waitForFunction(
() => {
return document.querySelector('zeppelin-note-import') !== null;
},
{ timeout: 10000 }
);
await this.page.waitForFunction(() => document.querySelector('zeppelin-note-import') !== null, { timeout: 10000 });
}

async testFilterFunctionality(filterTerm: string): Promise<void> {
await this.page.waitForLoadState('networkidle', { timeout: 10000 });
await this.homePage.filterNotes(filterTerm);

await this.page.waitForTimeout(1000);
const notebookTreeLocator = this.page.locator('nz-tree .node');

const filteredResults = await this.page.locator('nz-tree .node').count();
await notebookTreeLocator.first().waitFor({ state: 'attached', timeout: 15000 });
await expect(notebookTreeLocator.first()).toBeVisible({ timeout: 20000 });

const filteredResults = await notebookTreeLocator.count();
expect(filteredResults).toBeGreaterThanOrEqual(0);
}

Expand Down
2 changes: 1 addition & 1 deletion zeppelin-web-angular/e2e/models/workspace-page.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export class WorkspaceTestUtil {

async navigateAndWaitForLoad(): Promise<void> {
await this.workspacePage.navigateToWorkspace();
await waitForZeppelinReady(this.page);
await performLoginIfRequired(this.page);
await waitForZeppelinReady(this.page);
}

async verifyWorkspaceLayout(): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ test.describe('Home Page Note Operations', () => {
await page.goto('/');
await waitForZeppelinReady(page);
await performLoginIfRequired(page);
await page.waitForSelector('zeppelin-node-list', { timeout: 15000 });
const noteListLocator = page.locator('zeppelin-node-list');
await expect(noteListLocator).toBeVisible({ timeout: 15000 });
});

test.describe('Given note operations are available', () => {
Expand Down Expand Up @@ -93,13 +94,10 @@ test.describe('Home Page Note Operations', () => {

await page
.waitForFunction(
() => {
return (
document.querySelector('zeppelin-note-rename') !== null ||
document.querySelector('[role="dialog"]') !== null ||
document.querySelector('.ant-modal') !== null
);
},
() =>
document.querySelector('zeppelin-note-rename') !== null ||
document.querySelector('[role="dialog"]') !== null ||
document.querySelector('.ant-modal') !== null,
{ timeout: 5000 }
)
.catch(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ test.describe('Published Paragraph', () => {
await publishedParagraphPage.navigateToPublishedParagraph(noteId, paragraphId);

const modal = publishedParagraphPage.confirmationModal;
await expect(modal).toBeVisible();
await expect(modal).toBeVisible({ timeout: 300000 });

// Check for the new enhanced modal content
await expect(publishedParagraphPage.modalTitle).toHaveText('Run Paragraph?');
Expand Down
40 changes: 17 additions & 23 deletions zeppelin-web-angular/e2e/tests/theme/dark-mode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ test.describe('Dark Mode Theme Switching', () => {
await themePage.clearLocalStorage();
});

test('Scenario: User can switch to dark mode and persistence is maintained', async ({ page, context }) => {
let currentPage = page;

test('Scenario: User can switch to dark mode and persistence is maintained', async ({ page, browserName }) => {
// GIVEN: User is on the main page, which starts in 'system' mode by default (localStorage cleared).
await test.step('GIVEN the page starts in system mode', async () => {
await themePage.assertSystemTheme(); // Robot icon for system theme
Expand All @@ -41,32 +39,28 @@ test.describe('Dark Mode Theme Switching', () => {
// WHEN: Explicitly set theme to light mode for the rest of the test.
await test.step('WHEN the user explicitly sets theme to light mode', async () => {
await themePage.setThemeInLocalStorage('light');
await page.reload();
await page.waitForTimeout(500);
if (browserName === 'webkit') {
const currentUrl = page.url();
await page.goto(currentUrl, { waitUntil: 'load' });
} else {
page.reload();
}
await waitForZeppelinReady(page);
await themePage.assertLightTheme(); // Now it should be light mode with sun icon
});

// WHEN: User switches to dark mode by setting localStorage and reloading.
await test.step('WHEN the user switches to dark mode', async () => {
await test.step('WHEN the user explicitly sets theme to dark mode', async () => {
await themePage.setThemeInLocalStorage('dark');
const newPage = await context.newPage();
await newPage.goto(currentPage.url());
await waitForZeppelinReady(newPage);

// Update themePage to use newPage and verify dark mode
themePage = new ThemePage(newPage);
currentPage = newPage;
await themePage.assertDarkTheme();
});

// AND: User refreshes the page.
await test.step('AND the user refreshes the page', async () => {
await currentPage.reload();
await waitForZeppelinReady(currentPage);
});

// THEN: Dark mode is maintained after refresh.
await test.step('THEN dark mode is maintained after refresh', async () => {
await page.waitForTimeout(500);
if (browserName === 'webkit') {
const currentUrl = page.url();
await page.goto(currentUrl, { waitUntil: 'load' });
} else {
page.reload();
}
await waitForZeppelinReady(page);
await themePage.assertDarkTheme();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,7 @@ test.describe('Notebook Repository Item - Edit Mode', () => {
}

const firstRow = repoItemPage.settingRows.first();
const settingName =
(await firstRow
.locator('td')
.first()
.textContent()) || '';
const settingName = (await firstRow.locator('td').first().textContent()) || '';
const originalValue = await repoItemPage.getSettingValue(settingName);

await repoItemPage.clickEdit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,7 @@ test.describe('Notebook Repository Item - Form Validation', () => {
await repoItemPage.clickEdit();

const firstRow = repoItemPage.settingRows.first();
const settingName =
(await firstRow
.locator('td')
.first()
.textContent()) || '';
const settingName = (await firstRow.locator('td').first().textContent()) || '';

const isInputVisible = await repoItemPage.isInputVisible(settingName);
if (isInputVisible) {
Expand All @@ -73,11 +69,7 @@ test.describe('Notebook Repository Item - Form Validation', () => {
await repoItemPage.clickEdit();

const firstRow = repoItemPage.settingRows.first();
const settingName =
(await firstRow
.locator('td')
.first()
.textContent()) || '';
const settingName = (await firstRow.locator('td').first().textContent()) || '';

const isInputVisible = await repoItemPage.isInputVisible(settingName);
if (isInputVisible) {
Expand All @@ -102,11 +94,7 @@ test.describe('Notebook Repository Item - Form Validation', () => {

for (let i = 0; i < settingRows; i++) {
const row = repoItemPage.settingRows.nth(i);
const settingName =
(await row
.locator('td')
.first()
.textContent()) || '';
const settingName = (await row.locator('td').first().textContent()) || '';

const isInputVisible = await repoItemPage.isInputVisible(settingName);
if (isInputVisible) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,7 @@ test.describe('Notebook Repository Item - Settings', () => {

for (let i = 0; i < settingRows; i++) {
const row = repoItemPage.settingRows.nth(i);
const settingName =
(await row
.locator('td')
.first()
.textContent()) || '';
const settingName = (await row.locator('td').first().textContent()) || '';

const isInputVisible = await repoItemPage.isInputVisible(settingName);
if (isInputVisible) {
Expand All @@ -86,11 +82,7 @@ test.describe('Notebook Repository Item - Settings', () => {

for (let i = 0; i < settingRows; i++) {
const row = repoItemPage.settingRows.nth(i);
const settingName =
(await row
.locator('td')
.first()
.textContent()) || '';
const settingName = (await row.locator('td').first().textContent()) || '';

const isDropdownVisible = await repoItemPage.isDropdownVisible(settingName);
if (isDropdownVisible) {
Expand All @@ -112,11 +104,7 @@ test.describe('Notebook Repository Item - Settings', () => {
let foundInput = false;
for (let i = 0; i < settingRows; i++) {
const row = repoItemPage.settingRows.nth(i);
const settingName =
(await row
.locator('td')
.first()
.textContent()) || '';
const settingName = (await row.locator('td').first().textContent()) || '';

const isInputVisible = await repoItemPage.isInputVisible(settingName);
if (isInputVisible) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,7 @@ test.describe('Notebook Repository Item - Edit Workflow', () => {
let foundSetting = false;
for (let i = 0; i < settingRows; i++) {
const row = repoItemPage.settingRows.nth(i);
const settingName =
(await row
.locator('td')
.first()
.textContent()) || '';
const settingName = (await row.locator('td').first().textContent()) || '';

const isInputVisible = await repoItemPage.isInputVisible(settingName);
if (isInputVisible) {
Expand Down Expand Up @@ -91,11 +87,7 @@ test.describe('Notebook Repository Item - Edit Workflow', () => {
await repoItemUtil.verifyDisplayMode();

const firstRow = repoItemPage.settingRows.first();
const settingName =
(await firstRow
.locator('td')
.first()
.textContent()) || '';
const settingName = (await firstRow.locator('td').first().textContent()) || '';
const originalValue = await repoItemPage.getSettingValue(settingName);

await repoItemPage.clickEdit();
Expand Down
4 changes: 3 additions & 1 deletion zeppelin-web-angular/e2e/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ export function getCoverageTransformPaths(): string[] {
}

export async function waitForUrlNotContaining(page: Page, fragment: string) {
await page.waitForURL(url => !url.toString().includes(fragment));
await page.waitForLoadState('domcontentloaded', { timeout: 10000 });
await page.waitForURL(url => !url.toString().includes(fragment), { timeout: 15000 });
}

export function getCurrentPath(page: Page): string {
Expand Down Expand Up @@ -183,6 +184,7 @@ export async function performLoginIfRequired(page: Page): Promise<boolean> {
await loginButton.click();

await page.waitForSelector('text=Welcome to Zeppelin!', { timeout: 5000 });
await page.waitForLoadState('networkidle');
return true;
}

Expand Down
Loading
Loading