Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
047ea6a
Remove unused locators and methods in home-page.ts
tbonelee Nov 11, 2025
da40ed4
Refactor HomePageUtil: use readonly properties, simplify waitForFunct…
tbonelee Nov 11, 2025
7e38c7d
Refactor NotebookReposPageUtil and NotebookRepoItemUtil: remove unuse…
tbonelee Nov 11, 2025
8e39a58
Remove unused `selectSettingDropdown` method from `notebook-repos-pag…
tbonelee Nov 11, 2025
22b616e
Refactor WorkspaceTestUtil: use readonly properties for page and work…
tbonelee Nov 11, 2025
be80d7b
Refactor AnonymousLoginRedirect test: remove unused parameters.
tbonelee Nov 11, 2025
ba5bc9e
Remove unused `page` parameter from home-page-enhanced-functionality …
tbonelee Nov 11, 2025
dec5ce9
Remove unused `HomePage` instance and simplify waitForFunction call i…
tbonelee Nov 11, 2025
bf34a61
Remove unused `page` parameter from home-page-notebook-actions E2E te…
tbonelee Nov 11, 2025
2ddaffe
Remove `any` type in login.spec.ts
tbonelee Nov 11, 2025
bc80227
Remove unused `context` parameter from dark-mode E2E test.
tbonelee Nov 11, 2025
3995f7c
Remove unused `NotebookRepoItemUtil` instance from notebook-repo-item…
tbonelee Nov 11, 2025
030f902
Remove unused `NotebookRepoItemUtil` instance from notebook-repo-item…
tbonelee Nov 11, 2025
e60ee00
Remove unused `NotebookRepoItemUtil` instance from notebook-repo-item…
tbonelee Nov 11, 2025
91d6c11
Remove unused `NotebookUtil` import from e2e/utils.ts.
tbonelee Nov 11, 2025
73c91e7
Remove unused `HomePageUtil` import and instance from home-page-layou…
tbonelee Nov 11, 2025
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
55 changes: 0 additions & 55 deletions zeppelin-web-angular/e2e/models/home-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ export class HomePage extends BasePage {
readonly helpSection: Locator;
readonly communitySection: Locator;
readonly createNewNoteButton: Locator;
readonly importNoteButton: Locator;
readonly searchInput: Locator;
readonly filterInput: Locator;
readonly zeppelinLogo: Locator;
readonly anonymousUserIndicator: Locator;
readonly welcomeSection: Locator;
Expand All @@ -31,7 +28,6 @@ export class HomePage extends BasePage {
readonly helpCommunityColumn: Locator;
readonly welcomeDescription: Locator;
readonly refreshNoteButton: Locator;
readonly refreshIcon: Locator;
readonly notebookList: Locator;
readonly notebookHeading: Locator;
readonly helpHeading: Locator;
Expand Down Expand Up @@ -70,9 +66,6 @@ export class HomePage extends BasePage {
this.helpSection = page.locator('text=Help').first();
this.communitySection = page.locator('text=Community').first();
this.createNewNoteButton = page.locator('text=Create new Note');
this.importNoteButton = page.locator('text=Import Note');
this.searchInput = page.locator('textbox', { hasText: 'Search' });
this.filterInput = page.locator('input[placeholder*="Filter"]');
this.zeppelinLogo = page.locator('text=Zeppelin').first();
this.anonymousUserIndicator = page.locator('text=anonymous');
this.welcomeSection = page.locator('.welcome');
Expand All @@ -81,7 +74,6 @@ export class HomePage extends BasePage {
this.helpCommunityColumn = page.locator('[nz-col]').last();
this.welcomeDescription = page.locator('.welcome').getByText('Zeppelin is web-based notebook');
this.refreshNoteButton = page.locator('a.refresh-note');
this.refreshIcon = page.locator('a.refresh-note i[nz-icon]');
this.notebookList = page.locator('zeppelin-node-list');
this.notebookHeading = this.notebookColumn.locator('h3');
this.helpHeading = page.locator('h3').filter({ hasText: 'Help' });
Expand Down Expand Up @@ -150,18 +142,10 @@ export class HomePage extends BasePage {
await this.zeppelinLogo.click();
}

async getCurrentURL(): Promise<string> {
return this.page.url();
}

getCurrentPath(): string {
return getCurrentPath(this.page);
}

async getPageTitle(): Promise<string> {
return this.page.title();
}

async getWelcomeHeadingText(): Promise<string> {
const text = await this.welcomeHeading.textContent();
return text || '';
Expand Down Expand Up @@ -192,46 +176,7 @@ export class HomePage extends BasePage {
await this.nodeList.filterInput.fill(searchTerm);
}

async isRefreshIconSpinning(): Promise<boolean> {
const spinAttribute = await this.refreshIcon.getAttribute('nzSpin');
return spinAttribute === 'true' || spinAttribute === '';
}

async waitForRefreshToComplete(): Promise<void> {
await this.page.waitForFunction(
() => {
const icon = document.querySelector('a.refresh-note i[nz-icon]');
return icon && !icon.hasAttribute('nzSpin');
},
{ timeout: 10000 }
);
}

async getDocumentationLinkHref(): Promise<string | null> {
return this.externalLinks.documentation.getAttribute('href');
}

async areExternalLinksVisible(): Promise<boolean> {
const links = [
this.externalLinks.documentation,
this.externalLinks.mailingList,
this.externalLinks.issuesTracking,
this.externalLinks.github
];

for (const link of links) {
if (!(await link.isVisible())) {
return false;
}
}
return true;
}

async isWelcomeSectionVisible(): Promise<boolean> {
return this.welcomeSection.isVisible();
}

async isMoreInfoGridVisible(): Promise<boolean> {
return this.moreInfoGrid.isVisible();
}
}
18 changes: 4 additions & 14 deletions zeppelin-web-angular/e2e/models/home-page.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import { getBasicPageMetadata } from '../utils';
import { HomePage } from './home-page';

export class HomePageUtil {
private homePage: HomePage;
private page: Page;
private readonly homePage: HomePage;
private readonly page: Page;

constructor(page: Page) {
this.page = page;
Expand Down Expand Up @@ -183,23 +183,13 @@ 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> {
Expand Down
7 changes: 0 additions & 7 deletions zeppelin-web-angular/e2e/models/notebook-repos-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,6 @@ export class NotebookRepoItemPage {
await input.fill(value);
}

async selectSettingDropdown(settingName: string, optionValue: string): Promise<void> {
const row = this.repositoryCard.locator('tbody tr').filter({ hasText: settingName });
const select = row.locator('nz-select');
await select.click();
await this.page.locator(`nz-option[nzvalue="${optionValue}"]`).click();
}

async getSettingInputValue(settingName: string): Promise<string> {
const row = this.repositoryCard.locator('tbody tr').filter({ hasText: settingName });
const input = row.locator('input[nz-input]');
Expand Down
92 changes: 2 additions & 90 deletions zeppelin-web-angular/e2e/models/notebook-repos-page.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,21 @@ import { expect, Page } from '@playwright/test';
import { NotebookReposPage, NotebookRepoItemPage } from './notebook-repos-page';

export class NotebookReposPageUtil {
private notebookReposPage: NotebookReposPage;
private page: Page;
private readonly notebookReposPage: NotebookReposPage;

constructor(page: Page) {
this.page = page;
this.notebookReposPage = new NotebookReposPage(page);
}

async verifyPageStructure(): Promise<void> {
await expect(this.notebookReposPage.pageHeader).toBeVisible();
await expect(this.notebookReposPage.pageDescription).toBeVisible();
}

async verifyRepositoryListDisplayed(): Promise<void> {
const count = await this.notebookReposPage.getRepositoryItemCount();
expect(count).toBeGreaterThan(0);
}

async verifyAllRepositoriesRendered(): Promise<number> {
const count = await this.notebookReposPage.getRepositoryItemCount();
expect(count).toBeGreaterThan(0);
return count;
}

async getRepositoryItem(repoName: string): Promise<NotebookRepoItemPage> {
return new NotebookRepoItemPage(this.page, repoName);
}

async verifyRepositoryCardDisplayed(repoName: string): Promise<void> {
const repoItem = await this.getRepositoryItem(repoName);
await expect(repoItem.repositoryCard).toBeVisible();
await expect(repoItem.repositoryName).toContainText(repoName);
}
}

export class NotebookRepoItemUtil {
private repoItemPage: NotebookRepoItemPage;
private readonly repoItemPage: NotebookRepoItemPage;

constructor(page: Page, repoName: string) {
this.repoItemPage = new NotebookRepoItemPage(page, repoName);
Expand All @@ -68,70 +46,4 @@ export class NotebookRepoItemUtil {
const isEditMode = await this.repoItemPage.isEditMode();
expect(isEditMode).toBe(true);
}

async enterEditMode(): Promise<void> {
await this.repoItemPage.clickEdit();
await this.verifyEditMode();
}

async exitEditModeByCancel(): Promise<void> {
await this.repoItemPage.clickCancel();
await this.verifyDisplayMode();
}

async exitEditModeBySave(): Promise<void> {
await this.repoItemPage.clickSave();
await this.verifyDisplayMode();
}

async verifySettingsDisplayed(): Promise<void> {
const settingCount = await this.repoItemPage.getSettingCount();
expect(settingCount).toBeGreaterThan(0);
}

async verifyInputTypeSettingInEditMode(settingName: string): Promise<void> {
const isVisible = await this.repoItemPage.isInputVisible(settingName);
expect(isVisible).toBe(true);
}

async verifyDropdownTypeSettingInEditMode(settingName: string): Promise<void> {
const isVisible = await this.repoItemPage.isDropdownVisible(settingName);
expect(isVisible).toBe(true);
}

async updateInputSetting(settingName: string, value: string): Promise<void> {
await this.repoItemPage.fillSettingInput(settingName, value);
const inputValue = await this.repoItemPage.getSettingInputValue(settingName);
expect(inputValue).toBe(value);
}

async updateDropdownSetting(settingName: string, optionValue: string): Promise<void> {
await this.repoItemPage.selectSettingDropdown(settingName, optionValue);
}

async verifySaveButtonDisabled(): Promise<void> {
const isEnabled = await this.repoItemPage.isSaveButtonEnabled();
expect(isEnabled).toBe(false);
}

async verifySaveButtonEnabled(): Promise<void> {
const isEnabled = await this.repoItemPage.isSaveButtonEnabled();
expect(isEnabled).toBe(true);
}

async verifyFormReset(settingName: string, originalValue: string): Promise<void> {
const currentValue = await this.repoItemPage.getSettingValue(settingName);
expect(currentValue.trim()).toBe(originalValue.trim());
}

async performCompleteEditWorkflow(settingName: string, newValue: string, isInput: boolean = true): Promise<void> {
await this.enterEditMode();
if (isInput) {
await this.updateInputSetting(settingName, newValue);
} else {
await this.updateDropdownSetting(settingName, newValue);
}
await this.verifySaveButtonEnabled();
await this.exitEditModeBySave();
}
}
4 changes: 2 additions & 2 deletions zeppelin-web-angular/e2e/models/workspace-page.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import { performLoginIfRequired, waitForZeppelinReady } from '../utils';
import { WorkspacePage } from './workspace-page';

export class WorkspaceTestUtil {
private page: Page;
private workspacePage: WorkspacePage;
private readonly page: Page;
private readonly workspacePage: WorkspacePage;

constructor(page: Page) {
this.page = page;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ test.describe('Anonymous User Login Redirect', () => {
await waitForZeppelinReady(page);
});

test('When accessing login page directly, Then should redirect to home with proper URL change', async ({
page
}) => {
test('When accessing login page directly, Then should redirect to home with proper URL change', async () => {
const redirectResult = await homePageUtil.verifyAnonymousUserRedirectFromLogin();

expect(redirectResult.isLoginUrlMaintained).toBe(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,32 @@ test.describe('Home Page Enhanced Functionality', () => {
});

test.describe('Given documentation links are displayed', () => {
test('When documentation link is checked Then should have correct version in URL', async ({ page }) => {
test('When documentation link is checked Then should have correct version in URL', async () => {
await homeUtil.verifyDocumentationVersionLink();
});

test('When external links are checked Then should all open in new tab', async ({ page }) => {
test('When external links are checked Then should all open in new tab', async () => {
await homeUtil.verifyAllExternalLinksTargetBlank();
});
});

test.describe('Given welcome section display', () => {
test('When page loads Then should show welcome content with proper text', async ({ page }) => {
test('When page loads Then should show welcome content with proper text', async () => {
await homeUtil.verifyWelcomeSection();
});

test('When welcome section is displayed Then should contain interactive elements', async ({ page }) => {
test('When welcome section is displayed Then should contain interactive elements', async () => {
await homeUtil.verifyNotebookSection();
});
});

test.describe('Given community section content', () => {
test('When community section loads Then should display help and community headings', async ({ page }) => {
test('When community section loads Then should display help and community headings', async () => {
await homeUtil.verifyHelpSection();
await homeUtil.verifyCommunitySection();
});

test('When external links are displayed Then should show correct targets', async ({ page }) => {
test('When external links are displayed Then should show correct targets', async () => {
const linkTargets = await homeUtil.testExternalLinkTargets();

expect(linkTargets.documentationHref).toContain('zeppelin.apache.org/docs');
Expand Down
3 changes: 0 additions & 3 deletions zeppelin-web-angular/e2e/tests/home/home-page-layout.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

import { expect, test } from '@playwright/test';
import { HomePage } from '../../models/home-page';
import { HomePageUtil } from '../../models/home-page.util';
import { addPageAnnotationBeforeEach, performLoginIfRequired, waitForZeppelinReady, PAGES } from '../../utils';

test.describe('Home Page - Layout and Grid', () => {
Expand All @@ -26,8 +25,6 @@ test.describe('Home Page - Layout and Grid', () => {

test.describe('Responsive Grid Layout', () => {
test('should display responsive grid structure', async ({ page }) => {
const homePageUtil = new HomePageUtil(page);

await test.step('Given I am on the home page', async () => {
const homePage = new HomePage(page);
await homePage.navigateToHome();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,12 @@
*/

import { expect, test } from '@playwright/test';
import { HomePage } from '../../models/home-page';
import { addPageAnnotationBeforeEach, performLoginIfRequired, waitForZeppelinReady, PAGES } from '../../utils';

addPageAnnotationBeforeEach(PAGES.WORKSPACE.HOME);

test.describe('Home Page Note Operations', () => {
let homePage: HomePage;

test.beforeEach(async ({ page }) => {
homePage = new HomePage(page);
await page.goto('/');
await waitForZeppelinReady(page);
await performLoginIfRequired(page);
Expand Down Expand Up @@ -93,13 +89,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
Loading
Loading