This is an automated email from the ASF dual-hosted git repository.

jongyoul pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git


The following commit(s) were added to refs/heads/master by this push:
     new 076676aa87 [ZEPPELIN-6358] Remove anti-patterns of E2E and tidy test 
suite
076676aa87 is described below

commit 076676aa87f92b052619691c2788bd53771a266e
Author: YONGJAE LEE(이용재) <[email protected]>
AuthorDate: Sat Apr 4 21:04:45 2026 +0900

    [ZEPPELIN-6358] Remove anti-patterns of E2E and tidy test suite
    
    ### What is this PR for?
    Applied the [`e2e-reviewer`](https://github.com/dididy/e2e-skills) skill on 
the existing E2E suite. The skill does static analysis — it catches tests that 
can never actually fail, silent skips, swallowed errors in POM methods, that 
kind of thing.
    
    Findings and fixes:
    
    - `home-page-enhanced-functionality.spec.ts` was mostly duplicating 
`home-page-elements` and `home-page-note-operations` → deleted and merged
    - `toBeGreaterThanOrEqual(0)` and `toBeAttached()` on static elements were 
always passing → replaced with assertions that can fail
    - `if (isVisible) { expect() }` patterns silently skip when something 
breaks → removed or converted to `test.skip`
    - Several POM methods had `.catch(() => {})` with no comment → removed; 
kept the intentional ones and marked with `// JUSTIFIED:`
    - `document.querySelector` in `page.evaluate()` → swapped for Playwright 
locator API
    - Added `aria-label` / `data-testid` to action bar HTML; a few tests were 
breaking on DOM structure changes
    - Renamed a handful of tests whose names didn't match what they actually 
tested; dropped the ones that only called `toBeVisible()`
    
    
    ### What type of PR is it?
    Improvement
    Refactoring
    
    ### Todos
    
    ### What is the Jira issue?
    ZEPPELIN-6358
    
    ### How should this be tested?
    
    ### Screenshots (if appropriate)
    
    ### Questions:
    * Does the license files need to update? No
    * Is there breaking changes for older versions? No
    * Does this needs documentation? No
    
    
    Closes #5180 from dididy/tidy-e2e.
    
    Signed-off-by: Jongyoul Lee <[email protected]>
---
 .../e2e/models/about-zeppelin-modal.ts             |   4 -
 zeppelin-web-angular/e2e/models/base-page.ts       |  34 +-
 zeppelin-web-angular/e2e/models/home-page.ts       |  70 ++--
 zeppelin-web-angular/e2e/models/node-list-page.ts  |  14 +-
 .../e2e/models/note-create-modal.ts                |   4 -
 .../e2e/models/note-import-modal.ts                |  22 --
 .../e2e/models/notebook-repo-item.util.ts          |   6 +-
 .../e2e/models/notebook-repos-page.ts              |  36 +--
 zeppelin-web-angular/e2e/models/notebook.util.ts   |   6 +-
 zeppelin-web-angular/e2e/models/workspace-page.ts  |  23 --
 .../e2e/models/workspace-page.util.ts              |  60 ----
 zeppelin-web-angular/e2e/tests/app.spec.ts         | 128 +++-----
 .../anonymous-login-redirect.spec.ts               | 117 ++++---
 .../e2e/tests/home/home-page-elements.spec.ts      |  55 +---
 .../home/home-page-enhanced-functionality.spec.ts  |  92 ------
 .../tests/home/home-page-external-links.spec.ts    |  46 +--
 .../e2e/tests/home/home-page-layout.spec.ts        |  22 +-
 .../tests/home/home-page-note-operations.spec.ts   | 357 ++++++++++-----------
 .../tests/home/home-page-notebook-actions.spec.ts  |  57 ++--
 .../notebook/published/published-paragraph.spec.ts | 105 +++---
 .../about-zeppelin/about-zeppelin-modal.spec.ts    |  18 +-
 .../node-list/node-list-functionality.spec.ts      |  36 ++-
 .../share/note-create/note-create-modal.spec.ts    |  21 +-
 .../share/note-import/note-import-modal.spec.ts    |  18 +-
 .../e2e/tests/theme/dark-mode.spec.ts              |  12 +-
 .../notebook-repo-item-display.spec.ts             |  13 +-
 .../notebook-repos/notebook-repo-item-edit.spec.ts |  36 +--
 .../notebook-repo-item-form-validation.spec.ts     |  34 +-
 .../notebook-repo-item-settings.spec.ts            |  84 +++--
 .../notebook-repo-item-workflow.spec.ts            |  22 +-
 .../notebook-repos-page-structure.spec.ts          |  16 +-
 .../e2e/tests/workspace/workspace-main.spec.ts     |  48 +--
 zeppelin-web-angular/e2e/utils.ts                  |  12 +-
 zeppelin-web-angular/playwright.config.js          |   2 +-
 .../projects/zeppelin-react/package-lock.json      |   6 +-
 .../notebook/action-bar/action-bar.component.html  |   2 +-
 36 files changed, 549 insertions(+), 1089 deletions(-)

diff --git a/zeppelin-web-angular/e2e/models/about-zeppelin-modal.ts 
b/zeppelin-web-angular/e2e/models/about-zeppelin-modal.ts
index d5a44add77..a61632d3e6 100644
--- a/zeppelin-web-angular/e2e/models/about-zeppelin-modal.ts
+++ b/zeppelin-web-angular/e2e/models/about-zeppelin-modal.ts
@@ -43,10 +43,6 @@ export class AboutZeppelinModal extends BasePage {
     return (await this.versionText.textContent()) || '';
   }
 
-  async isLogoVisible(): Promise<boolean> {
-    return this.logo.isVisible();
-  }
-
   async getGetInvolvedHref(): Promise<string | null> {
     return this.getInvolvedLink.getAttribute('href');
   }
diff --git a/zeppelin-web-angular/e2e/models/base-page.ts 
b/zeppelin-web-angular/e2e/models/base-page.ts
index 539f096cbb..aa37f1a138 100644
--- a/zeppelin-web-angular/e2e/models/base-page.ts
+++ b/zeppelin-web-angular/e2e/models/base-page.ts
@@ -24,8 +24,6 @@ export class BasePage {
   readonly zeppelinHeader: Locator;
 
   readonly modalTitle: Locator;
-  readonly modalBody: Locator;
-  readonly modalContent: Locator;
 
   readonly okButton: Locator;
   readonly cancelButton: Locator;
@@ -41,8 +39,6 @@ export class BasePage {
     this.zeppelinHeader = page.locator('zeppelin-header');
 
     this.modalTitle = page.locator('.ant-modal-confirm-title, 
.ant-modal-title');
-    this.modalBody = page.locator('.ant-modal-confirm-content, 
.ant-modal-body');
-    this.modalContent = page.locator('.ant-modal-body');
 
     this.okButton = page.locator('button:has-text("OK")');
     this.cancelButton = page.locator('button:has-text("Cancel")');
@@ -71,11 +67,6 @@ export class BasePage {
     await this.navigateToRoute('/');
   }
 
-  getCurrentPath(): string {
-    const url = new URL(this.page.url());
-    return url.hash || url.pathname;
-  }
-
   async waitForUrlNotContaining(fragment: string): Promise<void> {
     await this.page.waitForURL(url => !url.toString().includes(fragment));
   }
@@ -85,14 +76,8 @@ export class BasePage {
   }
 
   async waitForFormLabels(labelTexts: string[], timeout = 10000): 
Promise<void> {
-    await this.page.waitForFunction(
-      texts => {
-        const labels = Array.from(document.querySelectorAll('nz-form-label'));
-        return texts.some(text => labels.some(l => 
l.textContent?.includes(text)));
-      },
-      labelTexts,
-      { timeout }
-    );
+    const locators = labelTexts.map(text => this.page.locator('nz-form-label', 
{ hasText: text }));
+    await Promise.race(locators.map(l => l.waitFor({ state: 'attached', 
timeout })));
   }
 
   async waitForElementAttribute(
@@ -109,25 +94,20 @@ export class BasePage {
     }
   }
 
-  async waitForRouterOutletChild(timeout = 10000): Promise<void> {
-    await expect(this.page.locator('zeppelin-workspace router-outlet + 
*')).toHaveCount(1, { timeout });
-  }
-
   async fillAndVerifyInput(
     locator: Locator,
     value: string,
     options?: { timeout?: number; clearFirst?: boolean }
   ): Promise<void> {
-    const { timeout = 10000, clearFirst = true } = options || {};
+    const { timeout = 10000 } = options || {};
 
     await expect(locator).toBeVisible({ timeout });
     await expect(locator).toBeEnabled({ timeout: 5000 });
 
-    if (clearFirst) {
-      await locator.clear();
-    }
-
+    // Click first so Angular's form control is focused and its initial 
setValue cycle
+    // has completed before we overwrite it.  Then fill() atomically sets the 
value.
+    await locator.click();
     await locator.fill(value);
-    await expect(locator).toHaveValue(value);
+    await expect(locator).toHaveValue(value, { timeout: 10000 });
   }
 }
diff --git a/zeppelin-web-angular/e2e/models/home-page.ts 
b/zeppelin-web-angular/e2e/models/home-page.ts
index 81f5085790..3222fc3964 100644
--- a/zeppelin-web-angular/e2e/models/home-page.ts
+++ b/zeppelin-web-angular/e2e/models/home-page.ts
@@ -17,8 +17,6 @@ export class HomePage extends BasePage {
   readonly notebookSection: Locator;
   readonly helpSection: Locator;
   readonly communitySection: Locator;
-  readonly zeppelinLogo: Locator;
-  readonly anonymousUserIndicator: Locator;
   readonly welcomeSection: Locator;
   readonly moreInfoGrid: Locator;
   readonly notebookColumn: Locator;
@@ -28,9 +26,6 @@ export class HomePage extends BasePage {
   readonly notebookHeading: Locator;
   readonly helpHeading: Locator;
   readonly communityHeading: Locator;
-  readonly createNoteModal: Locator;
-  readonly createNoteButton: Locator;
-  readonly notebookNameInput: Locator;
   readonly externalLinks: {
     documentation: Locator;
     mailingList: Locator;
@@ -41,13 +36,12 @@ export class HomePage extends BasePage {
     createNewNoteLink: Locator;
     importNoteLink: Locator;
     filterInput: Locator;
-    tree: Locator;
-    noteActions: {
-      renameNote: Locator;
-      clearOutput: Locator;
-      moveToTrash: Locator;
-    };
   };
+  readonly anonymousUserIndicator: Locator;
+  private readonly zeppelinLogo: Locator;
+  private readonly createNoteModal: Locator;
+  private readonly createNoteButton: Locator;
+  private readonly notebookNameInput: Locator;
 
   constructor(page: Page) {
     super(page);
@@ -58,8 +52,8 @@ export class HomePage extends BasePage {
     this.anonymousUserIndicator = page.locator('text=anonymous');
     this.welcomeSection = page.locator('.welcome');
     this.moreInfoGrid = page.locator('.more-info');
-    this.notebookColumn = page.locator('[nz-col]').first();
-    this.helpCommunityColumn = page.locator('[nz-col]').last();
+    this.notebookColumn = page.locator('[nz-col]').first(); // first() — left 
column contains the Notebook section
+    this.helpCommunityColumn = page.locator('[nz-col]').last(); // last() — 
right column contains Help and Community sections
     this.welcomeDescription = page.locator('.welcome').getByText('Zeppelin is 
web-based notebook');
     this.refreshNoteButton = page.locator('a.refresh-note');
     this.notebookHeading = this.notebookColumn.locator('h3');
@@ -79,13 +73,7 @@ export class HomePage extends BasePage {
     this.nodeList = {
       createNewNoteLink: page.locator('zeppelin-node-list a').filter({ 
hasText: 'Create new Note' }),
       importNoteLink: page.locator('zeppelin-node-list a').filter({ hasText: 
'Import Note' }),
-      filterInput: page.locator('zeppelin-node-list 
input[placeholder*="Filter"]'),
-      tree: page.locator('zeppelin-node-list nz-tree'),
-      noteActions: {
-        renameNote: page.locator('.file .operation a[nztooltiptitle*="Rename 
note"]'),
-        clearOutput: page.locator('.file .operation a[nztooltiptitle*="Clear 
output"]'),
-        moveToTrash: page.locator('.file .operation a[nztooltiptitle*="Move 
note to Trash"]')
-      }
+      filterInput: page.locator('zeppelin-node-list 
input[placeholder*="Filter"]')
     };
   }
 
@@ -100,14 +88,6 @@ export class HomePage extends BasePage {
     await this.waitForUrlNotContaining('#/login');
   }
 
-  async isHomeContentDisplayed(): Promise<boolean> {
-    return this.welcomeTitle.isVisible();
-  }
-
-  async isAnonymousUser(): Promise<boolean> {
-    return this.anonymousUserIndicator.isVisible();
-  }
-
   async clickZeppelinLogo(): Promise<void> {
     await this.zeppelinLogo.click({ timeout: 15000 });
   }
@@ -117,19 +97,11 @@ export class HomePage extends BasePage {
     return text || '';
   }
 
-  async getWelcomeDescriptionText(): Promise<string> {
-    const text = await this.welcomeDescription.textContent();
-    return text || '';
-  }
-
   async clickRefreshNotes(): Promise<void> {
+    await this.refreshNoteButton.waitFor({ state: 'visible', timeout: 10000 });
     await this.refreshNoteButton.click({ timeout: 15000 });
   }
 
-  async isNotebookListVisible(): Promise<boolean> {
-    return this.zeppelinNodeList.isVisible();
-  }
-
   async clickCreateNewNote(): Promise<void> {
     await this.nodeList.createNewNoteLink.click({ timeout: 15000 });
     await this.createNoteModal.waitFor({ state: 'visible' });
@@ -141,7 +113,7 @@ export class HomePage extends BasePage {
     // Wait for the modal form to be fully rendered with proper labels
     await this.page.waitForSelector('nz-form-label', { timeout: 10000 });
 
-    await this.waitForFormLabels(['Note Name', 'Clone Note']);
+    await this.waitForFormLabels(['Note Name']);
 
     // Fill and verify the notebook name input
     await this.fillAndVerifyInput(this.notebookNameInput, notebookName);
@@ -149,7 +121,9 @@ export class HomePage extends BasePage {
     // Click the 'Create' button in the modal
     await expect(this.createNoteButton).toBeEnabled({ timeout: 5000 });
     await this.createNoteButton.click({ timeout: 15000 });
-    await this.waitForPageLoad();
+    // Wait for navigation to the notebook page — confirms the note was 
created server-side.
+    // waitForPageLoad() (domcontentloaded) fires instantly on SPA routing and 
does not guarantee this.
+    await this.page.waitForURL(/\/notebook\//, { timeout: 45000 });
   }
 
   async clickImportNote(): Promise<void> {
@@ -159,19 +133,17 @@ 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, { timeout: 15000 });
-  }
-
-  async isRefreshIconSpinning(): Promise<boolean> {
-    const spinAttribute = await this.refreshIcon.getAttribute('nzSpin');
-    return spinAttribute === 'true' || spinAttribute === '';
+    // pressSequentially fires real key events so Angular's ngModel detects 
the change (fill() does not).
+    // Triple-click to select all, then type to replace or Backspace to clear.
+    await this.nodeList.filterInput.click({ clickCount: 3 });
+    if (searchTerm) {
+      await this.nodeList.filterInput.pressSequentially(searchTerm);
+    } else {
+      await this.nodeList.filterInput.press('Backspace');
+    }
   }
 
   async waitForRefreshToComplete(): Promise<void> {
     await this.waitForElementAttribute('a.refresh-note i[nz-icon]', 'nzSpin', 
false);
   }
-
-  async getDocumentationLinkHref(): Promise<string | null> {
-    return this.externalLinks.documentation.getAttribute('href');
-  }
 }
diff --git a/zeppelin-web-angular/e2e/models/node-list-page.ts 
b/zeppelin-web-angular/e2e/models/node-list-page.ts
index 17bd93de33..9c81bda02f 100644
--- a/zeppelin-web-angular/e2e/models/node-list-page.ts
+++ b/zeppelin-web-angular/e2e/models/node-list-page.ts
@@ -41,11 +41,7 @@ export class NodeListPage extends BasePage {
     await this.createNewNoteButton.click();
   }
 
-  getFolderByName(folderName: string): Locator {
-    return this.page.locator('nz-tree-node').filter({ hasText: folderName 
}).first();
-  }
-
-  getNoteByName(noteName: string): Locator {
+  private getNoteByName(noteName: string): Locator {
     return this.page.locator('nz-tree-node').filter({ hasText: noteName 
}).first();
   }
 
@@ -56,14 +52,6 @@ export class NodeListPage extends BasePage {
     await noteLink.click();
   }
 
-  async isFilterInputVisible(): Promise<boolean> {
-    return this.filterInput.isVisible();
-  }
-
-  async isTrashFolderVisible(): Promise<boolean> {
-    return this.trashFolder.isVisible();
-  }
-
   async getAllVisibleNoteNames(): Promise<string[]> {
     const noteElements = await this.notes.all();
     const names: string[] = [];
diff --git a/zeppelin-web-angular/e2e/models/note-create-modal.ts 
b/zeppelin-web-angular/e2e/models/note-create-modal.ts
index 1e1a0c4808..a00ef19219 100644
--- a/zeppelin-web-angular/e2e/models/note-create-modal.ts
+++ b/zeppelin-web-angular/e2e/models/note-create-modal.ts
@@ -47,8 +47,4 @@ export class NoteCreateModal extends BasePage {
   async clickCreate(): Promise<void> {
     await this.createButton.click();
   }
-
-  async isFolderInfoVisible(): Promise<boolean> {
-    return this.folderInfoAlert.isVisible();
-  }
 }
diff --git a/zeppelin-web-angular/e2e/models/note-import-modal.ts 
b/zeppelin-web-angular/e2e/models/note-import-modal.ts
index 11db6d5da4..e4634f94bc 100644
--- a/zeppelin-web-angular/e2e/models/note-import-modal.ts
+++ b/zeppelin-web-angular/e2e/models/note-import-modal.ts
@@ -59,16 +59,6 @@ export class NoteImportModal extends BasePage {
     await this.urlTab.click();
   }
 
-  async isJsonFileTabSelected(): Promise<boolean> {
-    const ariaSelected = await this.jsonFileTab.getAttribute('aria-selected');
-    return ariaSelected === 'true';
-  }
-
-  async isUrlTabSelected(): Promise<boolean> {
-    const ariaSelected = await this.urlTab.getAttribute('aria-selected');
-    return ariaSelected === 'true';
-  }
-
   async setImportUrl(url: string): Promise<void> {
     await this.urlInput.fill(url);
   }
@@ -77,19 +67,7 @@ export class NoteImportModal extends BasePage {
     await this.importNoteButton.click();
   }
 
-  async isImportNoteButtonDisabled(): Promise<boolean> {
-    return this.importNoteButton.isDisabled();
-  }
-
   async getFileSizeLimit(): Promise<string> {
     return (await this.fileSizeLimit.textContent()) || '';
   }
-
-  async isErrorAlertVisible(): Promise<boolean> {
-    return this.errorAlert.isVisible();
-  }
-
-  async getErrorMessage(): Promise<string> {
-    return (await this.errorAlert.textContent()) || '';
-  }
 }
diff --git a/zeppelin-web-angular/e2e/models/notebook-repo-item.util.ts 
b/zeppelin-web-angular/e2e/models/notebook-repo-item.util.ts
index 06cdab7ed2..333af7c417 100644
--- a/zeppelin-web-angular/e2e/models/notebook-repo-item.util.ts
+++ b/zeppelin-web-angular/e2e/models/notebook-repo-item.util.ts
@@ -24,14 +24,12 @@ export class NotebookRepoItemUtil extends BasePage {
 
   async verifyDisplayMode(): Promise<void> {
     await expect(this.repoItemPage.editButton).toBeVisible();
-    const isEditMode = await this.repoItemPage.isEditMode();
-    expect(isEditMode).toBe(false);
+    await expect(this.repoItemPage.repositoryCard).not.toHaveClass(/\bedit\b/);
   }
 
   async verifyEditMode(): Promise<void> {
     await expect(this.repoItemPage.saveButton).toBeVisible();
     await expect(this.repoItemPage.cancelButton).toBeVisible();
-    const isEditMode = await this.repoItemPage.isEditMode();
-    expect(isEditMode).toBe(true);
+    await expect(this.repoItemPage.repositoryCard).toHaveClass(/\bedit\b/);
   }
 }
diff --git a/zeppelin-web-angular/e2e/models/notebook-repos-page.ts 
b/zeppelin-web-angular/e2e/models/notebook-repos-page.ts
index 3272df477d..66234f5b61 100644
--- a/zeppelin-web-angular/e2e/models/notebook-repos-page.ts
+++ b/zeppelin-web-angular/e2e/models/notebook-repos-page.ts
@@ -34,10 +34,6 @@ export class NotebookReposPage extends BasePage {
       this.page.waitForSelector('zeppelin-notebook-repo-item', { state: 
'visible' })
     ]);
   }
-
-  async getRepositoryItemCount(): Promise<number> {
-    return await this.repositoryItems.count();
-  }
 }
 
 export class NotebookRepoItemPage extends BasePage {
@@ -72,20 +68,6 @@ export class NotebookRepoItemPage extends BasePage {
     await this.cancelButton.click({ timeout: 15000 });
   }
 
-  async isEditMode(): Promise<boolean> {
-    return await this.repositoryCard.evaluate(el => 
el.classList.contains('edit'));
-  }
-
-  async isSaveButtonEnabled(): Promise<boolean> {
-    return await this.saveButton.isEnabled();
-  }
-
-  async getSettingValue(settingName: string): Promise<string> {
-    const row = this.repositoryCard.locator('tbody tr').filter({ hasText: 
settingName });
-    const valueCell = row.locator('td').nth(1);
-    return (await valueCell.textContent()) || '';
-  }
-
   async fillSettingInput(settingName: string, value: string): Promise<void> {
     const row = this.repositoryCard.locator('tbody tr').filter({ hasText: 
settingName });
     const input = row.locator('input[nz-input]');
@@ -93,29 +75,15 @@ export class NotebookRepoItemPage extends BasePage {
     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({ timeout: 15000 });
-    await this.page.locator(`nz-option[nzvalue="${optionValue}"]`).click({ 
timeout: 15000 });
-  }
-
   async getSettingInputValue(settingName: string): Promise<string> {
     const row = this.repositoryCard.locator('tbody tr').filter({ hasText: 
settingName });
     const input = row.locator('input[nz-input]');
     return await input.inputValue();
   }
 
-  async isInputVisible(settingName: string): Promise<boolean> {
-    const row = this.repositoryCard.locator('tbody tr').filter({ hasText: 
settingName });
-    const input = row.locator('input[nz-input]');
-    return await input.isVisible();
-  }
-
-  async isDropdownVisible(settingName: string): Promise<boolean> {
+  async getSettingValue(settingName: string): Promise<string> {
     const row = this.repositoryCard.locator('tbody tr').filter({ hasText: 
settingName });
-    const select = row.locator('nz-select');
-    return await select.isVisible();
+    return (await row.locator('td').nth(1).textContent()) || '';
   }
 
   async getSettingCount(): Promise<number> {
diff --git a/zeppelin-web-angular/e2e/models/notebook.util.ts 
b/zeppelin-web-angular/e2e/models/notebook.util.ts
index 00e8dbc183..98ee1d9648 100644
--- a/zeppelin-web-angular/e2e/models/notebook.util.ts
+++ b/zeppelin-web-angular/e2e/models/notebook.util.ts
@@ -33,10 +33,8 @@ export class NotebookUtil extends BasePage {
     await waitForZeppelinReady(this.page);
 
     // Wait for URL to not contain 'login' and for the notebook list to appear
-    await this.page.waitForFunction(
-      () => !window.location.href.includes('#/login') && 
document.querySelector('zeppelin-node-list') !== null,
-      { timeout: 30000 }
-    );
+    await this.page.waitForURL(url => !url.toString().includes('#/login'), { 
timeout: 30000 });
+    await this.page.locator('zeppelin-node-list').waitFor({ state: 'attached', 
timeout: 30000 });
 
     await expect(this.homePage.zeppelinNodeList).toBeVisible({ timeout: 90000 
});
     await this.homePage.createNote(notebookName);
diff --git a/zeppelin-web-angular/e2e/models/workspace-page.ts 
b/zeppelin-web-angular/e2e/models/workspace-page.ts
deleted file mode 100644
index 1fdcf9e5a7..0000000000
--- a/zeppelin-web-angular/e2e/models/workspace-page.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *     http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { Locator, Page } from '@playwright/test';
-import { BasePage } from './base-page';
-
-export class WorkspacePage extends BasePage {
-  readonly routerOutlet: Locator;
-
-  constructor(page: Page) {
-    super(page);
-    this.routerOutlet = page.locator('zeppelin-workspace router-outlet');
-  }
-}
diff --git a/zeppelin-web-angular/e2e/models/workspace-page.util.ts 
b/zeppelin-web-angular/e2e/models/workspace-page.util.ts
deleted file mode 100644
index 8ed557b66d..0000000000
--- a/zeppelin-web-angular/e2e/models/workspace-page.util.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *     http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { expect, Page } from '@playwright/test';
-import { BasePage } from './base-page';
-import { WorkspacePage } from './workspace-page';
-import { performLoginIfRequired, waitForZeppelinReady } from '../utils';
-
-export class WorkspaceUtil extends BasePage {
-  private workspacePage: WorkspacePage;
-
-  constructor(page: Page) {
-    super(page);
-    this.workspacePage = new WorkspacePage(page);
-  }
-
-  async navigateAndWaitForLoad(): Promise<void> {
-    await this.workspacePage.navigateToWorkspace();
-    await performLoginIfRequired(this.page);
-    await waitForZeppelinReady(this.page);
-  }
-
-  async verifyWorkspaceLayout(): Promise<void> {
-    await expect(this.workspacePage.workspaceComponent).toBeVisible();
-    await expect(this.workspacePage.routerOutlet).toBeAttached();
-  }
-
-  async verifyHeaderVisibility(shouldBeVisible: boolean): Promise<void> {
-    if (shouldBeVisible) {
-      await expect(this.workspacePage.zeppelinHeader).toBeVisible();
-    } else {
-      await expect(this.workspacePage.zeppelinHeader).toBeHidden();
-    }
-  }
-
-  async verifyRouterOutletActivation(): Promise<void> {
-    await expect(this.workspacePage.routerOutlet).toBeAttached();
-    await this.waitForRouterOutletChild();
-  }
-
-  async waitForComponentActivation(): Promise<void> {
-    await this.page.waitForFunction(
-      () => {
-        const workspace = document.querySelector('zeppelin-workspace');
-        const content = workspace?.querySelector('.content');
-        return content && content.children.length > 1;
-      },
-      { timeout: 15000 }
-    );
-  }
-}
diff --git a/zeppelin-web-angular/e2e/tests/app.spec.ts 
b/zeppelin-web-angular/e2e/tests/app.spec.ts
index 5d956c747f..d637896e0b 100644
--- a/zeppelin-web-angular/e2e/tests/app.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/app.spec.ts
@@ -29,64 +29,47 @@ test.describe('Zeppelin App Component', () => {
   test('should have correct component selector and structure', async ({ page 
}) => {
     await basePage.waitForPageLoad();
 
-    // Test zeppelin-root selector
-    const zeppelinRoot = page.locator('zeppelin-root');
-    await expect(zeppelinRoot).toBeAttached();
-
     await waitForZeppelinReady(page);
 
     // Verify router-outlet is inside zeppelin-root (use first to avoid 
multiple elements)
-    const routerOutlet = zeppelinRoot.locator('router-outlet').first();
-    await expect(routerOutlet).toBeAttached();
+    const zeppelinRoot = page.locator('zeppelin-root');
+
+    // Verify routing has activated by checking that actual content is 
rendered inside the workspace
+    await expect(zeppelinRoot.locator('zeppelin-workspace')).toBeVisible();
 
     // Check for loading spinner
     const loadingSpinner = zeppelinRoot.locator('zeppelin-spin').filter({ 
hasText: 'Getting Ticket Data' });
     const logoutSpinner = zeppelinRoot.locator('zeppelin-spin').filter({ 
hasText: 'Logging out' });
 
-    // Loading spinner should exist, logout spinner may or may not exist 
depending on conditions
-    const loadingSpinnerCount = await loadingSpinner.count();
-    const logoutSpinnerCount = await logoutSpinner.count();
-
-    expect(loadingSpinnerCount).toBeGreaterThanOrEqual(0);
-    expect(logoutSpinnerCount).toBeGreaterThanOrEqual(0);
+    // After waitForZeppelinReady, both spinners must be gone
+    await expect(loadingSpinner).toHaveCount(0);
+    await expect(logoutSpinner).toHaveCount(0);
   });
 
   test('should have proper page title', async ({ page }) => {
     await expect(page).toHaveTitle(/Zeppelin/);
   });
 
-  test('should display workspace after loading', async ({ page }) => {
+  test('should display home content after loading', async ({ page }) => {
     await waitForZeppelinReady(page);
     // After the `beforeEach` hook, which handles login, the workspace should 
be visible.
     await expect(basePage.zeppelinWorkspace).toBeVisible();
+    // Verify the home page content is rendered (not just a blank shell)
+    await 
expect(basePage.zeppelinWorkspace.locator('zeppelin-home')).toBeVisible();
   });
 
-  test('should handle navigation events correctly', async ({ page }) => {
+  test('should hide loading spinner after navigation', async ({ page }) => {
     await waitForZeppelinReady(page);
 
-    // Test navigation back to root path
-    try {
-      await page.goto('/', { waitUntil: 'load', timeout: 10000 });
-
-      // Check if loading spinner appears during navigation
-      const loadingSpinner = page.locator('zeppelin-spin').filter({ hasText: 
'Getting Ticket Data' });
-
-      // Loading might be very fast, so we check if it exists
-      const spinnerCount = await loadingSpinner.count();
-      expect(spinnerCount).toBeGreaterThanOrEqual(0);
-
-      await waitForZeppelinReady(page);
+    await page.goto('/', { waitUntil: 'load', timeout: 10000 });
+    await waitForZeppelinReady(page);
 
-      // After ready, loading should be hidden if it was visible
-      if (await loadingSpinner.isVisible()) {
-        await expect(loadingSpinner).toBeHidden();
-      }
-    } catch (error) {
-      console.log('Navigation test skipped due to timeout:', error);
-    }
+    // After the app is ready, the loading spinner must be hidden
+    const loadingSpinner = page.locator('zeppelin-spin').filter({ hasText: 
'Getting Ticket Data' });
+    await expect(loadingSpinner).toBeHidden();
   });
 
-  test('should properly manage loading state observable', async ({ page }) => {
+  test('should hide loading spinner after page reload', async ({ page }) => {
     await basePage.waitForPageLoad();
 
     // Test that loading$ observable works correctly
@@ -95,55 +78,44 @@ test.describe('Zeppelin App Component', () => {
     // Reload page to trigger loading state
     await page.reload({ waitUntil: 'load' });
 
-    // Check loading state during page load
-    const initialLoadingVisible = await loadingSpinner.isVisible();
-
-    if (initialLoadingVisible) {
-      await expect(loadingSpinner).toBeVisible();
-      await expect(loadingSpinner).toContainText('Getting Ticket Data ...');
-    }
+    // If the spinner is briefly visible during reload, it will resolve; just 
wait for ready
 
     // Wait for loading to complete
     await waitForZeppelinReady(page);
     await expect(loadingSpinner).toBeHidden();
   });
 
-  test('should handle logout observable correctly', async ({ page }) => {
+  test('should show logout spinner when logging out', async ({ page }) => {
     await waitForZeppelinReady(page);
 
+    // Only test logout flow for authenticated (non-anonymous) users — skip 
before any assertions
+    const statusElement = page.locator('.status');
+    await expect(statusElement).toBeVisible();
+    const statusText = await statusElement.textContent();
+    test.skip(statusText?.includes('anonymous') ?? false, 'Logout spinner only 
applies to authenticated users');
+
     const logoutSpinner = page.locator('zeppelin-spin').filter({ hasText: 
'Logging out' });
 
     // Initially logout spinner should be hidden
     await expect(logoutSpinner).toBeHidden();
 
-    // Check if we have a logout mechanism available
-    const statusElement = page.locator('.status');
-    if (await statusElement.isVisible()) {
-      const statusText = await statusElement.textContent();
-
-      if (statusText && !statusText.includes('anonymous')) {
-        // If not anonymous user, test logout spinner
-        await statusElement.click();
-        const logoutButton = page.getByRole('link', { name: 'Logout' });
-
-        if (await logoutButton.isVisible()) {
-          await logoutButton.click();
-
-          // Logout spinner should appear
-          await expect(logoutSpinner).toBeVisible();
-          await expect(logoutSpinner).toContainText('Logging out ...');
-        }
-      }
-    }
+    await statusElement.click();
+    const logoutButton = page.getByRole('link', { name: 'Logout' });
+
+    // If the dropdown has no Logout link, auth is not configured — skip 
gracefully
+    const logoutCount = await logoutButton.count();
+    test.skip(logoutCount === 0, 'Logout option not available — auth not 
configured in this environment');
+
+    await logoutButton.click();
+
+    await expect(logoutSpinner).toBeVisible();
+    await expect(logoutSpinner).toContainText('Logging out ...');
   });
 
   test('should maintain component integrity during navigation', async ({ page 
}) => {
     await waitForZeppelinReady(page);
     await performLoginIfRequired(page);
 
-    const zeppelinRoot = page.locator('zeppelin-root');
-    const routerOutlet = zeppelinRoot.locator('router-outlet').first();
-
     // Navigate to different pages and ensure component remains intact
     const testPaths = ['/#/notebook', '/#/jobmanager', '/#/configuration'];
 
@@ -151,36 +123,12 @@ test.describe('Zeppelin App Component', () => {
       await page.goto(path, { waitUntil: 'load', timeout: 10000 });
       await waitForZeppelinReady(page);
 
-      // Component should still be attached
-      await expect(zeppelinRoot).toBeAttached();
-
-      // Router outlet should still be present
-      await expect(routerOutlet).toBeAttached();
+      // Workspace must render visible content after each navigation (confirms 
Angular didn't unmount the root component)
+      await expect(page.locator('zeppelin-workspace')).toBeVisible();
     }
 
     // Return to home
     await page.goto('/', { waitUntil: 'load' });
     await waitForZeppelinReady(page);
-    await expect(zeppelinRoot).toBeAttached();
-  });
-
-  test('should verify spinner text content and visibility', async ({ page }) 
=> {
-    await basePage.waitForPageLoad();
-
-    // Check exact text content of spinners
-    const loadingSpinner = page.locator('zeppelin-spin').filter({ hasText: 
'Getting Ticket Data' });
-    const logoutSpinner = page.locator('zeppelin-spin').filter({ hasText: 
'Logging out' });
-
-    // Verify spinner elements exist
-    expect(await loadingSpinner.count()).toBeGreaterThanOrEqual(0);
-    expect(await logoutSpinner.count()).toBeGreaterThanOrEqual(0);
-
-    // If loading spinner is visible, check its exact text
-    if (await loadingSpinner.isVisible()) {
-      await expect(loadingSpinner).toHaveText('Getting Ticket Data ...');
-    }
-
-    // Logout spinner should not be visible initially
-    await expect(logoutSpinner).toBeHidden();
   });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/authentication/anonymous-login-redirect.spec.ts
 
b/zeppelin-web-angular/e2e/tests/authentication/anonymous-login-redirect.spec.ts
index 5e73dc036d..3189863e13 100644
--- 
a/zeppelin-web-angular/e2e/tests/authentication/anonymous-login-redirect.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/authentication/anonymous-login-redirect.spec.ts
@@ -54,27 +54,35 @@ test.describe('Anonymous User Login Redirect', () => {
 
       const currentPath = getCurrentPath(page);
       const isLoginUrlMaintained = currentPath.includes('#/login');
-      const isHomeContentDisplayed = await homePage.isHomeContentDisplayed();
-      const isAnonymousUser = await homePage.isAnonymousUser();
 
       expect(isLoginUrlMaintained).toBe(false);
-      expect(isHomeContentDisplayed).toBe(true);
-      expect(isAnonymousUser).toBe(true);
+      await expect(homePage.welcomeTitle).toBeVisible();
+      await expect(homePage.anonymousUserIndicator).toBeVisible();
       expect(currentPath).toContain('#/');
       expect(currentPath).not.toContain('#/login');
     });
 
-    test('When accessing login page directly, Then should display all home 
page elements correctly', async ({
+    test('When accessing login page directly, Then should display full home 
page with all sections and links', async ({
       page
     }) => {
       await page.goto('/#/login');
       await waitForZeppelinReady(page);
       await page.waitForURL(url => !url.toString().includes('#/login'));
 
+      // Sections
       await expect(homePage.welcomeTitle).toBeVisible();
       await expect(homePage.notebookSection).toBeVisible();
       await expect(homePage.helpSection).toBeVisible();
       await expect(homePage.communitySection).toBeVisible();
+      // Notebook actions
+      await expect(homePage.nodeList.createNewNoteLink).toBeVisible();
+      await expect(homePage.nodeList.importNoteLink).toBeVisible();
+      await expect(homePage.nodeList.filterInput).toBeVisible();
+      // External links
+      await expect(homePage.externalLinks.documentation).toBeVisible();
+      await expect(homePage.externalLinks.mailingList).toBeVisible();
+      await expect(homePage.externalLinks.issuesTracking).toBeVisible();
+      await expect(homePage.externalLinks.github).toBeVisible();
     });
 
     test('When clicking Zeppelin logo after redirect, Then should maintain 
home URL and content', async ({ page }) => {
@@ -86,12 +94,11 @@ test.describe('Anonymous User Login Redirect', () => {
       await homePage.clickZeppelinLogo();
       await basePage.waitForPageLoad();
       const pathAfterClick = getCurrentPath(page);
-      const homeContentMaintained = await homePage.isHomeContentDisplayed();
 
       expect(pathBeforeClick).toContain('#/');
       expect(pathBeforeClick).not.toContain('#/login');
       expect(pathAfterClick).toContain('#/');
-      expect(homeContentMaintained).toBe(true);
+      await expect(homePage.welcomeTitle).toBeVisible();
     });
 
     test('When accessing login page, Then should redirect and maintain 
anonymous user state', async ({ page }) => {
@@ -100,89 +107,75 @@ test.describe('Anonymous User Login Redirect', () => {
       await page.waitForURL(url => !url.toString().includes('#/login'));
 
       const basicMetadata = await getBasicPageMetadata(page);
-      const isAnonymous = await homePage.isAnonymousUser();
 
       expect(basicMetadata.title).toContain('Zeppelin');
       expect(basicMetadata.path).toContain('#/');
       expect(basicMetadata.path).not.toContain('#/login');
-      expect(isAnonymous).toBe(true);
+      await expect(homePage.anonymousUserIndicator).toBeVisible();
     });
 
-    test('When accessing login page, Then should display welcome heading and 
main sections', async ({ page }) => {
-      await page.goto('/#/login');
+    test('When navigating between home and login URLs, Then should maintain 
consistent user experience', async ({
+      page
+    }) => {
+      await page.goto('/#/');
       await waitForZeppelinReady(page);
-      await page.waitForURL(url => !url.toString().includes('#/login'));
 
-      await expect(basePage.welcomeTitle).toBeVisible();
-      await expect(page.locator('text=Notebook').first()).toBeVisible();
-      await expect(page.locator('text=Help').first()).toBeVisible();
-      await expect(page.locator('text=Community').first()).toBeVisible();
-    });
+      const homeMetadata = await getBasicPageMetadata(page);
+      expect(homeMetadata.path).toContain('#/');
+      await expect(homePage.anonymousUserIndicator).toBeVisible();
 
-    test('When accessing login page, Then should display notebook 
functionalities', async ({ page }) => {
       await page.goto('/#/login');
       await waitForZeppelinReady(page);
       await page.waitForURL(url => !url.toString().includes('#/login'));
 
-      await expect(page.locator('text=Create new Note')).toBeVisible();
-      await expect(page.locator('text=Import Note')).toBeVisible();
+      const loginMetadata = await getBasicPageMetadata(page);
+      expect(loginMetadata.path).toContain('#/');
+      expect(loginMetadata.path).not.toContain('#/login');
+      await expect(homePage.anonymousUserIndicator).toBeVisible();
 
-      const filterInput = page.locator('input[placeholder*="Filter"]');
-      if ((await filterInput.count()) > 0) {
-        await expect(filterInput).toBeVisible();
-      }
+      await homePage.navigateToLogin();
+      await expect(homePage.welcomeTitle).toBeVisible();
     });
 
-    test('When accessing login page, Then should display external links in 
help and community sections', async ({
+    test('When accessing protected route directly, Then should load home 
content for anonymous user', async ({
       page
     }) => {
-      await page.goto('/#/login');
+      // Notebook-repos is a management route; anonymous users should either 
access it or be redirected home
+      await page.goto('/#/notebook-repos');
       await waitForZeppelinReady(page);
-      await page.waitForURL(url => !url.toString().includes('#/login'));
 
-      const docLinks = page.locator('a[href*="zeppelin.apache.org/docs"]');
-      const communityLinks = page.locator('a[href*="community.html"]');
-      const issuesLinks = page.locator('a[href*="issues.apache.org"]');
-      const githubLinks = 
page.locator('a[href*="github.com/apache/zeppelin"]');
+      // Then: Either the notebook-repos page loads (anonymous mode allows it) 
OR
+      // the user is redirected back to home — both are valid; the app must 
not crash or show an empty shell
+      const currentPath = getCurrentPath(page);
 
-      if ((await docLinks.count()) > 0) {
-        await expect(docLinks).toBeVisible();
-      }
-      if ((await communityLinks.count()) > 0) {
-        await expect(communityLinks).toBeVisible();
-      }
-      if ((await issuesLinks.count()) > 0) {
-        await expect(issuesLinks).toBeVisible();
-      }
-      if ((await githubLinks.count()) > 0) {
-        await expect(githubLinks).toBeVisible();
+      await expect(homePage.anonymousUserIndicator).toBeVisible();
+      // The app root must still be rendering — not a blank white page
+      await expect(basePage.zeppelinWorkspace).toBeVisible();
+      // If redirected, must land on home (not an error page)
+      if (!currentPath.includes('#/notebook-repos')) {
+        // JUSTIFIED: both states are valid — notebook-repos accessible OR 
redirect to home; only assert welcomeTitle on redirect path
+        await expect(basePage.welcomeTitle).toBeVisible();
       }
     });
 
-    test('When navigating between home and login URLs, Then should maintain 
consistent user experience', async ({
+    test('When accessing configuration route directly, Then should handle 
navigation for anonymous user', async ({
       page
     }) => {
-      await page.goto('/#/');
+      // Configuration is a management route; anonymous users should either 
access it or be redirected home
+      await page.goto('/#/configuration');
       await waitForZeppelinReady(page);
 
-      const homeMetadata = await getBasicPageMetadata(page);
-      const isHomeAnonymous = await homePage.isAnonymousUser();
-      expect(homeMetadata.path).toContain('#/');
-      expect(isHomeAnonymous).toBe(true);
-
-      await page.goto('/#/login');
-      await waitForZeppelinReady(page);
-      await page.waitForURL(url => !url.toString().includes('#/login'));
-
-      const loginMetadata = await getBasicPageMetadata(page);
-      const isLoginAnonymous = await homePage.isAnonymousUser();
-      expect(loginMetadata.path).toContain('#/');
-      expect(loginMetadata.path).not.toContain('#/login');
-      expect(isLoginAnonymous).toBe(true);
+      // Then: Either the configuration page loads (anonymous mode allows it) 
OR
+      // the user is redirected back to home — both are valid; the app must 
not crash
+      const currentPath = getCurrentPath(page);
 
-      await homePage.navigateToLogin();
-      const isHomeContentDisplayed = await homePage.isHomeContentDisplayed();
-      expect(isHomeContentDisplayed).toBe(true);
+      await expect(homePage.anonymousUserIndicator).toBeVisible();
+      await expect(basePage.zeppelinWorkspace).toBeVisible();
+      if (!currentPath.includes('#/configuration')) {
+        // JUSTIFIED: both states are valid — in anonymous mode (no shiro.ini) 
all routes including
+        // /configuration are accessible; shiro.ini url rules control whether 
this route is restricted
+        await expect(basePage.welcomeTitle).toBeVisible({ timeout: 15000 });
+      }
     });
 
     test('When multiple page loads occur on login URL, Then should 
consistently redirect to home', async ({ page }) => {
@@ -192,7 +185,7 @@ test.describe('Anonymous User Login Redirect', () => {
         await waitForUrlNotContaining(page, '#/login');
 
         await expect(basePage.welcomeTitle).toBeVisible();
-        await expect(page.locator('text=anonymous')).toBeVisible();
+        await expect(page.getByText('anonymous', { exact: true 
})).toBeVisible();
 
         const path = getCurrentPath(page);
         expect(path).toContain('#/');
diff --git a/zeppelin-web-angular/e2e/tests/home/home-page-elements.spec.ts 
b/zeppelin-web-angular/e2e/tests/home/home-page-elements.spec.ts
index f41c00c544..cac761ae85 100644
--- a/zeppelin-web-angular/e2e/tests/home/home-page-elements.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/home/home-page-elements.spec.ts
@@ -47,29 +47,6 @@ test.describe('Home Page - Core Elements', () => {
         expect(welcomeText).toContain('interactive data analytics');
       });
     });
-
-    test('should have proper welcome message structure', async () => {
-      await test.step('Given I am on the home page', async () => {
-        await homePage.navigateToHome();
-      });
-
-      await test.step('When I examine the welcome section', async () => {
-        await expect(homePage.welcomeSection).toBeVisible();
-      });
-
-      await test.step('Then I should see the welcome heading', async () => {
-        await expect(homePage.welcomeTitle).toBeVisible();
-        const headingText = await homePage.getWelcomeHeadingText();
-        expect(headingText.trim()).toBe('Welcome to Zeppelin!');
-      });
-
-      await test.step('And I should see the welcome description', async () => {
-        await expect(homePage.welcomeDescription).toBeVisible();
-        const descriptionText = await homePage.getWelcomeDescriptionText();
-        expect(descriptionText).toContain('web-based notebook');
-        expect(descriptionText).toContain('interactive data analytics');
-      });
-    });
   });
 
   test.describe('Notebook Section', () => {
@@ -85,13 +62,13 @@ test.describe('Home Page - Core Elements', () => {
       await test.step('Then I should see all notebook section components', 
async () => {
         await expect(homePage.notebookSection).toBeVisible();
         await expect(homePage.notebookHeading).toBeVisible();
+        await expect(homePage.notebookHeading).toContainText('Notebook');
         await expect(homePage.refreshNoteButton).toBeVisible();
-        await page.waitForSelector('zeppelin-node-list', { timeout: 10000 });
         await expect(homePage.zeppelinNodeList).toBeVisible();
       });
     });
 
-    test('should have functional refresh notes button', async () => {
+    test('should keep notebook list visible after refresh', async () => {
       await test.step('Given I am on the home page with notebook section 
visible', async () => {
         await homePage.navigateToHome();
         await expect(homePage.refreshNoteButton).toBeVisible();
@@ -104,24 +81,6 @@ test.describe('Home Page - Core Elements', () => {
       await test.step('Then the notebook list should still be visible', async 
() => {
         await homePage.waitForRefreshToComplete();
         await expect(homePage.zeppelinNodeList).toBeVisible();
-        const isStillVisible = await homePage.zeppelinNodeList.isVisible();
-        expect(isStillVisible).toBe(true);
-      });
-    });
-
-    test('should display notebook list component', async ({ page }) => {
-      await test.step('Given I am on the home page', async () => {
-        await homePage.navigateToHome();
-      });
-
-      await test.step('When I look for the notebook list', async () => {
-        await waitForZeppelinReady(page);
-      });
-
-      await test.step('Then I should see the notebook list component', async 
() => {
-        await expect(homePage.zeppelinNodeList).toBeVisible();
-        const isVisible = await homePage.isNotebookListVisible();
-        expect(isVisible).toBe(true);
       });
     });
   });
@@ -148,7 +107,7 @@ test.describe('Home Page - Core Elements', () => {
   });
 
   test.describe('Community Section', () => {
-    test('should display community section with all links', async ({ page }) 
=> {
+    test('should display community section heading', async ({ page }) => {
       await test.step('Given I am on the home page', async () => {
         await homePage.navigateToHome();
       });
@@ -160,14 +119,10 @@ test.describe('Home Page - Core Elements', () => {
       await test.step('Then I should see the community section', async () => {
         await expect(homePage.communitySection).toBeVisible();
         await expect(homePage.communityHeading).toBeVisible();
+        await expect(homePage.communityHeading).toContainText('Community');
       });
 
-      await test.step('And I should see all community links', async () => {
-        await expect(homePage.externalLinks.documentation).toBeVisible();
-        await expect(homePage.externalLinks.mailingList).toBeVisible();
-        await expect(homePage.externalLinks.issuesTracking).toBeVisible();
-        await expect(homePage.externalLinks.github).toBeVisible();
-      });
+      // External link href/target/icon assertions are covered by 
home-page-external-links.spec.ts
     });
   });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/home/home-page-enhanced-functionality.spec.ts 
b/zeppelin-web-angular/e2e/tests/home/home-page-enhanced-functionality.spec.ts
deleted file mode 100644
index fb3a56cbc2..0000000000
--- 
a/zeppelin-web-angular/e2e/tests/home/home-page-enhanced-functionality.spec.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *     http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-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 Enhanced Functionality', () => {
-  let homePage: HomePage;
-
-  test.beforeEach(async ({ page }) => {
-    homePage = new HomePage(page);
-    await page.goto('/#/');
-    await waitForZeppelinReady(page);
-    await performLoginIfRequired(page);
-  });
-
-  test.describe('Given documentation links are displayed', () => {
-    test('When documentation link is checked Then should have correct version 
in URL', async () => {
-      const href = await homePage.getDocumentationLinkHref();
-      expect(href).toContain('zeppelin.apache.org/docs');
-      expect(href).toMatch(/\/docs\/\d+\.\d+\.\d+(-SNAPSHOT)?\//);
-    });
-
-    test('When external links are checked Then should all open in new tab', 
async () => {
-      const links = [
-        homePage.externalLinks.documentation,
-        homePage.externalLinks.mailingList,
-        homePage.externalLinks.issuesTracking,
-        homePage.externalLinks.github
-      ];
-
-      for (const link of links) {
-        const target = await link.getAttribute('target');
-        expect(target).toBe('_blank');
-      }
-    });
-  });
-
-  test.describe('Given welcome section display', () => {
-    test('When page loads Then should show welcome content with proper text', 
async () => {
-      await expect(homePage.welcomeSection).toBeVisible();
-      await expect(homePage.welcomeTitle).toBeVisible();
-      const headingText = await homePage.getWelcomeHeadingText();
-      expect(headingText.trim()).toBe('Welcome to Zeppelin!');
-      await expect(homePage.welcomeDescription).toBeVisible();
-      const welcomeText = await homePage.welcomeDescription.textContent();
-      expect(welcomeText).toContain('web-based notebook');
-      expect(welcomeText).toContain('interactive data analytics');
-    });
-
-    test('When welcome section is displayed Then should contain interactive 
elements', async ({ page }) => {
-      await expect(homePage.notebookSection).toBeVisible();
-      await expect(homePage.notebookHeading).toBeVisible();
-      await expect(homePage.refreshNoteButton).toBeVisible();
-      await page.waitForSelector('zeppelin-node-list', { timeout: 10000 });
-      await expect(homePage.zeppelinNodeList).toBeVisible();
-    });
-  });
-
-  test.describe('Given community section content', () => {
-    test('When community section loads Then should display help and community 
headings', async () => {
-      await expect(homePage.helpSection).toBeVisible();
-      await expect(homePage.helpHeading).toBeVisible();
-      await expect(homePage.communitySection).toBeVisible();
-      await expect(homePage.communityHeading).toBeVisible();
-    });
-
-    test('When external links are displayed Then should show correct targets', 
async () => {
-      const docHref = await 
homePage.externalLinks.documentation.getAttribute('href');
-      const mailHref = await 
homePage.externalLinks.mailingList.getAttribute('href');
-      const issuesHref = await 
homePage.externalLinks.issuesTracking.getAttribute('href');
-      const githubHref = await 
homePage.externalLinks.github.getAttribute('href');
-
-      expect(docHref).toContain('zeppelin.apache.org/docs');
-      expect(mailHref).toContain('community.html');
-      expect(issuesHref).toContain('issues.apache.org');
-      expect(githubHref).toContain('github.com/apache/zeppelin');
-    });
-  });
-});
diff --git 
a/zeppelin-web-angular/e2e/tests/home/home-page-external-links.spec.ts 
b/zeppelin-web-angular/e2e/tests/home/home-page-external-links.spec.ts
index ce44eb967b..97a250d6ab 100644
--- a/zeppelin-web-angular/e2e/tests/home/home-page-external-links.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/home/home-page-external-links.spec.ts
@@ -28,18 +28,13 @@ test.describe('Home Page - External Links', () => {
 
   test.describe('Documentation Link', () => {
     test('should have correct documentation link with dynamic version', async 
() => {
-      await test.step('Given I am on the home page', async () => {
-        await homePage.navigateToHome();
-      });
-
       await test.step('When I examine the documentation link', async () => {
         await expect(homePage.externalLinks.documentation).toBeVisible();
       });
 
       await test.step('Then it should have the correct href pattern', async () 
=> {
         const href = await 
homePage.externalLinks.documentation.getAttribute('href');
-        expect(href).toContain('zeppelin.apache.org/docs');
-        expect(href).toContain('index.html');
+        expect(href).toMatch(/\/docs\/\d+\.\d+\.\d+(-SNAPSHOT)?\/index\.html/);
       });
 
       await test.step('And it should open in a new tab', async () => {
@@ -51,10 +46,6 @@ test.describe('Home Page - External Links', () => {
 
   test.describe('Community Links', () => {
     test('should have correct mailing list link', async () => {
-      await test.step('Given I am on the home page', async () => {
-        await homePage.navigateToHome();
-      });
-
       await test.step('When I examine the mailing list link', async () => {
         await expect(homePage.externalLinks.mailingList).toBeVisible();
       });
@@ -76,10 +67,6 @@ test.describe('Home Page - External Links', () => {
     });
 
     test('should have correct issues tracking link', async () => {
-      await test.step('Given I am on the home page', async () => {
-        await homePage.navigateToHome();
-      });
-
       await test.step('When I examine the issues tracking link', async () => {
         await expect(homePage.externalLinks.issuesTracking).toBeVisible();
       });
@@ -101,10 +88,6 @@ test.describe('Home Page - External Links', () => {
     });
 
     test('should have correct GitHub link', async () => {
-      await test.step('Given I am on the home page', async () => {
-        await homePage.navigateToHome();
-      });
-
       await test.step('When I examine the GitHub link', async () => {
         await expect(homePage.externalLinks.github).toBeVisible();
       });
@@ -125,31 +108,4 @@ test.describe('Home Page - External Links', () => {
       });
     });
   });
-
-  test.describe('Link Verification', () => {
-    test('should have all external links with proper attributes', async () => {
-      await test.step('Given I am on the home page', async () => {
-        await homePage.navigateToHome();
-      });
-
-      await test.step('When I examine all external links', async () => {
-        await expect(homePage.externalLinks.documentation).toBeVisible();
-        await expect(homePage.externalLinks.mailingList).toBeVisible();
-        await expect(homePage.externalLinks.issuesTracking).toBeVisible();
-        await expect(homePage.externalLinks.github).toBeVisible();
-      });
-
-      await test.step('Then all links should open in new tabs', async () => {
-        const docTarget = await 
homePage.externalLinks.documentation.getAttribute('target');
-        const mailTarget = await 
homePage.externalLinks.mailingList.getAttribute('target');
-        const issuesTarget = await 
homePage.externalLinks.issuesTracking.getAttribute('target');
-        const githubTarget = await 
homePage.externalLinks.github.getAttribute('target');
-
-        expect(docTarget).toBe('_blank');
-        expect(mailTarget).toBe('_blank');
-        expect(issuesTarget).toBe('_blank');
-        expect(githubTarget).toBe('_blank');
-      });
-    });
-  });
 });
diff --git a/zeppelin-web-angular/e2e/tests/home/home-page-layout.spec.ts 
b/zeppelin-web-angular/e2e/tests/home/home-page-layout.spec.ts
index e960c3c6cb..5a12f6ea4e 100644
--- a/zeppelin-web-angular/e2e/tests/home/home-page-layout.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/home/home-page-layout.spec.ts
@@ -27,16 +27,6 @@ test.describe('Home Page - Layout and Grid', () => {
   });
 
   test.describe('Responsive Grid Layout', () => {
-    test('should display responsive grid structure', async ({ page }) => {
-      await test.step('Given I am on the home page', async () => {
-        await homePage.navigateToHome();
-      });
-
-      await test.step('When the page loads', async () => {
-        await waitForZeppelinReady(page);
-      });
-    });
-
     test('should have proper column distribution', async () => {
       await test.step('Given I am on the home page', async () => {
         await homePage.navigateToHome();
@@ -58,6 +48,7 @@ test.describe('Home Page - Layout and Grid', () => {
       await test.step('And I should see the help/community column with proper 
sizing', async () => {
         await expect(homePage.helpCommunityColumn).toBeVisible();
         // Check that the column contains help and community content
+        // JUSTIFIED: Help heading comes before Community heading in the 
right-column DOM order
         const helpHeading = homePage.helpCommunityColumn.locator('h3').first();
         await expect(helpHeading).toBeVisible();
         const helpText = await helpHeading.textContent();
@@ -78,6 +69,12 @@ test.describe('Home Page - Layout and Grid', () => {
         await expect(homePage.moreInfoGrid).toBeVisible();
         await expect(homePage.notebookColumn).toBeVisible();
         await expect(homePage.helpCommunityColumn).toBeVisible();
+        // Verify headings are readable and contain expected text at tablet 
width
+        const notebookHeading = homePage.notebookColumn.locator('h3');
+        // JUSTIFIED: Help heading comes before Community heading in the 
right-column DOM order
+        const helpHeading = homePage.helpCommunityColumn.locator('h3').first();
+        await expect(notebookHeading).toContainText('Notebook');
+        await expect(helpHeading).toContainText('Help');
       });
 
       await test.step('When I resize to mobile view', async () => {
@@ -89,11 +86,14 @@ test.describe('Home Page - Layout and Grid', () => {
         await expect(homePage.notebookColumn).toBeVisible();
         await expect(homePage.helpCommunityColumn).toBeVisible();
 
-        // Verify content is still accessible in mobile view
+        // Verify headings are readable and contain expected text in mobile 
view
         const notebookHeading = homePage.notebookColumn.locator('h3');
+        // JUSTIFIED: Help heading comes before Community heading in the 
right-column DOM order
         const helpHeading = homePage.helpCommunityColumn.locator('h3').first();
         await expect(notebookHeading).toBeVisible();
+        await expect(notebookHeading).toContainText('Notebook');
         await expect(helpHeading).toBeVisible();
+        await expect(helpHeading).toContainText('Help');
       });
     });
   });
diff --git 
a/zeppelin-web-angular/e2e/tests/home/home-page-note-operations.spec.ts 
b/zeppelin-web-angular/e2e/tests/home/home-page-note-operations.spec.ts
index f385de5f58..66be0f6f4d 100644
--- a/zeppelin-web-angular/e2e/tests/home/home-page-note-operations.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/home/home-page-note-operations.spec.ts
@@ -18,235 +18,220 @@ addPageAnnotationBeforeEach(PAGES.WORKSPACE.HOME);
 
 test.describe('Home Page Note Operations', () => {
   let homePage: HomePage;
+  let testNoteName: string;
 
   test.beforeEach(async ({ page }) => {
     homePage = new HomePage(page);
+    testNoteName = `_e2e_ops_test_${Date.now()}`;
+
     await page.goto('/#/');
     await waitForZeppelinReady(page);
     await performLoginIfRequired(page);
-    const noteListLocator = page.locator('zeppelin-node-list');
-    await expect(noteListLocator).toBeVisible({ timeout: 15000 });
-  });
 
-  test.describe('Given note operations are available', () => {
-    test('When note list loads Then should show note action buttons on hover', 
async ({ page }) => {
-      const notesExist = await page.locator('.node .file').count();
+    // Create a test note so all operation tests have a real target
+    await homePage.createNote(testNoteName);
+    await page.goto('/#/');
+    await waitForZeppelinReady(page);
 
-      if (notesExist > 0) {
-        const firstNote = page.locator('.node .file').first();
-        await firstNote.hover();
+    await expect(page.locator('zeppelin-node-list')).toBeVisible({ timeout: 
15000 });
 
-        await 
expect(homePage.nodeList.noteActions.renameNote.first()).toBeVisible();
-        await 
expect(homePage.nodeList.noteActions.clearOutput.first()).toBeVisible();
-        await 
expect(homePage.nodeList.noteActions.moveToTrash.first()).toBeVisible();
-      } else {
-        console.log('No notes available for testing operations');
-      }
+    // Force a note list refresh so the newly created note is guaranteed to 
appear
+    await homePage.clickRefreshNotes();
+    await expect(page.locator('.node .file').filter({ hasText: testNoteName 
})).toBeVisible({ timeout: 15000 });
+  });
+
+  test.describe('Given note operations are available', () => {
+    test('When hovering over note Then should show rename, clear, and delete 
action buttons', async ({ page }) => {
+      const testNote = page.locator('.node .file').filter({ hasText: 
testNoteName });
+      await testNote.hover();
+
+      // Scoped to testNote: CSS .node:hover reveals .operation icons only for 
the hovered node
+      await expect(testNote.locator('.operation a[nztooltiptitle="Rename 
note"]')).toBeVisible();
+      await expect(testNote.locator('.operation a[nztooltiptitle="Clear 
output"]')).toBeVisible();
+      await expect(testNote.locator('.operation a[nztooltiptitle="Move note to 
Trash"]')).toBeVisible();
     });
 
     test('When hovering over note actions Then should show tooltip 
descriptions', async ({ page }) => {
-      const noteExists = await page
-        .locator('.node .file')
-        .first()
-        .isVisible()
-        .catch(() => false);
+      const testNote = page.locator('.node .file').filter({ hasText: 
testNoteName });
+      await testNote.hover();
+      // Wait for the buttons to become visible — CSS .node:hover makes <i> 
display:inline-block
+      const renameBtn = testNote.locator('.operation a[nztooltiptitle="Rename 
note"]');
+      const clearBtn = testNote.locator('.operation a[nztooltiptitle="Clear 
output"]');
+      const trashBtn = testNote.locator('.operation a[nztooltiptitle="Move 
note to Trash"]');
+      await renameBtn.waitFor({ state: 'visible' });
+
+      // dispatchEvent mouseenter — justified: nz-tooltip listens to 
mouseenter; direct hover() on a child
+      // causes a CSS :hover race where the mouse leaves the parent .node 
.file mid-movement, hiding the button.
+      await renameBtn.dispatchEvent('mouseenter');
+      await expect(page.locator('.ant-tooltip', { hasText: 'Rename note' 
})).toBeVisible();
+      await renameBtn.dispatchEvent('mouseleave');
+
+      await clearBtn.dispatchEvent('mouseenter');
+      await expect(page.locator('.ant-tooltip', { hasText: 'Clear output' 
})).toBeVisible();
+      await clearBtn.dispatchEvent('mouseleave');
+
+      await trashBtn.dispatchEvent('mouseenter');
+      await expect(page.locator('.ant-tooltip', { hasText: 'Move note to 
Trash' })).toBeVisible();
+      await trashBtn.dispatchEvent('mouseleave');
+    });
+  });
 
-      if (noteExists) {
-        const firstNote = page.locator('.node .file').first();
-        await firstNote.hover();
+  test.describe('Given rename note functionality', () => {
+    test('When rename button is clicked Then should open rename dialog', async 
({ page }) => {
+      const testNote = page.locator('.node .file').filter({ hasText: 
testNoteName });
+      await testNote.hover();
+
+      const renameButton = testNote.locator('.operation 
a[nztooltiptitle="Rename note"]');
+      await expect(renameButton).toBeVisible();
+      await renameButton.click();
+
+      // JUSTIFIED: compound selector targets rename dialog; first() picks the 
visible modal instance
+      await expect(page.locator('zeppelin-note-rename, 
[role="dialog"].ant-modal').first()).toBeVisible({
+        timeout: 5000
+      });
+    });
+  });
 
-        await 
expect(homePage.nodeList.noteActions.renameNote.first()).toBeVisible();
-        await 
expect(homePage.nodeList.noteActions.clearOutput.first()).toBeVisible();
-        await 
expect(homePage.nodeList.noteActions.moveToTrash.first()).toBeVisible();
+  test.describe('Given clear output functionality', () => {
+    test('When clear output button is clicked Then should show and dismiss 
confirmation dialog', async ({ page }) => {
+      const testNote = page.locator('.node .file').filter({ hasText: 
testNoteName });
+      await testNote.hover();
 
-        // Test tooltip visibility by hovering over each icon
-        await homePage.nodeList.noteActions.renameNote.first().hover();
-        await expect(page.locator('.ant-tooltip', { hasText: 'Rename note' 
})).toBeVisible();
+      const clearButton = testNote.locator('.operation a[nztooltiptitle="Clear 
output"]');
+      await expect(clearButton).toBeVisible();
+      await clearButton.click();
 
-        await homePage.nodeList.noteActions.clearOutput.first().hover();
-        await expect(page.locator('.ant-tooltip', { hasText: 'Clear output' 
})).toBeVisible();
+      await expect(page.locator('text=Do you want to clear all 
output?')).toBeVisible();
+      await page.locator('.ant-popover button:has-text("OK")').click();
 
-        await homePage.nodeList.noteActions.moveToTrash.first().hover();
-        await expect(page.locator('.ant-tooltip', { hasText: 'Move note to 
Trash' })).toBeVisible();
-      }
+      // Popover should close after confirming the operation
+      await expect(page.locator('text=Do you want to clear all 
output?')).not.toBeVisible();
     });
   });
 
-  test.describe('Given rename note functionality', () => {
-    test('When rename button is clicked Then should trigger rename workflow', 
async ({ page }) => {
-      const noteExists = await page
-        .locator('.node .file')
-        .first()
-        .isVisible()
-        .catch(() => false);
-
-      if (noteExists) {
-        const noteItem = page.locator('.node .file').first();
-        await noteItem.hover();
-
-        const renameButton = homePage.nodeList.noteActions.renameNote.first();
-        await expect(renameButton).toBeVisible();
-        await renameButton.click();
-
-        await page
-          .waitForFunction(
-            () =>
-              document.querySelector('zeppelin-note-rename') !== null ||
-              document.querySelector('[role="dialog"]') !== null ||
-              document.querySelector('.ant-modal') !== null,
-            { timeout: 5000 }
-          )
-          .catch(() => {
-            console.log('Rename modal did not appear - might need different 
trigger');
-          });
-      }
+  test.describe('Given move to trash functionality', () => {
+    test('When move to trash is confirmed Then should move note to trash 
folder', async ({ page }) => {
+      const testNote = page.locator('.node .file').filter({ hasText: 
testNoteName });
+      await testNote.hover();
+
+      const deleteButton = testNote.locator('.operation a[nztooltiptitle="Move 
note to Trash"]');
+      await expect(deleteButton).toBeVisible();
+      await deleteButton.click();
+
+      await expect(page.locator('text=This note will be moved to 
trash.')).toBeVisible();
+      await page.locator('.ant-popover button:has-text("OK")').click();
+
+      // Source note must disappear from the list — not just that Trash folder 
appears
+      await expect(testNote).not.toBeVisible({ timeout: 10000 });
+      await expect(page.locator('.node .folder').filter({ hasText: 'Trash' 
})).toBeVisible({ timeout: 10000 });
     });
   });
 
-  test.describe('Given clear output functionality', () => {
-    test('When clear output button is clicked Then should show confirmation 
dialog', async ({ page }) => {
-      const noteExists = await page
-        .locator('.node .file')
-        .first()
-        .isVisible()
-        .catch(() => false);
-
-      if (noteExists) {
-        const noteItem = page.locator('.node .file').first();
-        await noteItem.hover();
-
-        const clearButton = homePage.nodeList.noteActions.clearOutput.first();
-        await expect(clearButton).toBeVisible();
-        await clearButton.click();
-
-        await expect(page.locator('text=Do you want to clear all 
output?')).toBeVisible();
+  test.describe('Given note filter with special characters', () => {
+    test('When filtering with special characters Then should not crash and 
should dim non-matching results', async ({
+      page
+    }) => {
+      for (const char of ['#', '%', '"']) {
+        await homePage.filterNotes(char);
+
+        // App must not crash — node list container remains present
+        await expect(page.locator('zeppelin-node-list')).toBeVisible();
+        // Test note name contains none of these chars, so it must be dimmed 
(.not-matched class)
+        await expect(page.locator('.node').filter({ hasText: testNoteName 
})).toHaveClass(/not-matched/, {
+          timeout: 10000
+        });
       }
-    });
 
-    test('When clear output is confirmed Then should execute clear operation', 
async ({ page }) => {
-      const noteExists = await page
-        .locator('.node .file')
-        .first()
-        .isVisible()
-        .catch(() => false);
-
-      if (noteExists) {
-        const noteItem = page.locator('.node .file').first();
-        await noteItem.hover();
-
-        const clearButton = homePage.nodeList.noteActions.clearOutput.first();
-        await expect(clearButton).toBeVisible();
-        await clearButton.click();
-
-        const confirmButton = page.locator('button:has-text("Yes")');
-        if (await confirmButton.isVisible()) {
-          await confirmButton.click();
-        }
-      }
+      // Clearing filter restores the note (removes .not-matched)
+      await homePage.filterNotes('');
+      await expect(page.locator('.node').filter({ hasText: testNoteName 
})).not.toHaveClass(/not-matched/, {
+        timeout: 5000
+      });
     });
   });
 
-  test.describe('Given move to trash functionality', () => {
-    test('When delete button is clicked Then should show trash confirmation', 
async ({ page }) => {
-      const noteExists = await page
-        .locator('.node .file')
-        .first()
-        .isVisible()
-        .catch(() => false);
-
-      if (noteExists) {
-        const noteItem = page.locator('.node .file').first();
-        await noteItem.hover();
-
-        const deleteButton = homePage.nodeList.noteActions.moveToTrash.first();
-        await expect(deleteButton).toBeVisible();
-        await deleteButton.click();
-
-        await expect(page.locator('text=This note will be moved to 
trash.')).toBeVisible();
-      }
-    });
+  test.describe('Given max length note name input', () => {
+    test('When note name input is filled with a very long string Then input 
should cap or accept gracefully', async ({
+      page
+    }) => {
+      await homePage.clickCreateNewNote();
+      await page.waitForSelector('nz-form-label', { timeout: 10000 });
 
-    test('When move to trash is confirmed Then should move note to trash 
folder', async ({ page }) => {
-      const noteExists = await page
-        .locator('.node .file')
-        .first()
-        .isVisible()
-        .catch(() => false);
-
-      if (noteExists) {
-        const noteItem = page.locator('.node .file').first();
-        await noteItem.hover();
-
-        const deleteButton = homePage.nodeList.noteActions.moveToTrash.first();
-        await expect(deleteButton).toBeVisible();
-        await deleteButton.click();
-
-        const confirmButton = page.locator('button:has-text("Yes")');
-        if (await confirmButton.isVisible()) {
-          await confirmButton.click();
-
-          const trashFolder = page.locator('.node .folder').filter({ hasText: 
'Trash' });
-          await expect(trashFolder).toBeVisible();
-        }
+      const notebookNameInput = page.locator('div.ant-modal-content 
input[name="noteName"]');
+      const maxLengthAttr = await notebookNameInput.getAttribute('maxlength');
+      const longName = `_e2e_ml_${'a'.repeat(300)}`;
+
+      await notebookNameInput.fill(longName);
+      const actualValue = await notebookNameInput.inputValue();
+
+      // Must have content — input did not silently reject the fill
+      expect(actualValue.length).toBeGreaterThan(0);
+
+      if (maxLengthAttr !== null) {
+        // If the element enforces maxlength, the value must be capped at that 
limit
+        expect(actualValue.length).toBeLessThanOrEqual(parseInt(maxLengthAttr, 
10));
+      } else {
+        // No client-side cap — the full value passes through
+        expect(actualValue).toBe(longName);
       }
+
+      // Dismiss the modal without creating
+      await page.keyboard.press('Escape');
+      await page.locator('div.ant-modal-content').waitFor({ state: 'detached', 
timeout: 5000 });
     });
   });
 
   test.describe('Given trash folder operations', () => {
+    test.beforeEach(async ({ page }) => {
+      // Move the test note to trash to put the trash folder into a known state
+      const testNote = page.locator('.node .file').filter({ hasText: 
testNoteName });
+      await testNote.hover();
+      await testNote.locator('.operation').waitFor({ state: 'visible' });
+
+      const deleteButton = testNote.locator('.operation a[nztooltiptitle="Move 
note to Trash"]');
+      await deleteButton.click();
+
+      await expect(page.locator('text=This note will be moved to 
trash.')).toBeVisible();
+      await page.locator('.ant-popover button:has-text("OK")').click();
+      await expect(page.locator('.node .folder').filter({ hasText: 'Trash' 
})).toBeVisible({ timeout: 10000 });
+    });
+
     test('When trash folder exists Then should show restore and empty 
options', async ({ page }) => {
-      const trashExists = await page
-        .locator('.node .folder')
-        .filter({ hasText: 'Trash' })
-        .isVisible()
-        .catch(() => false);
-
-      if (trashExists) {
-        const trashFolder = page.locator('.node .folder').filter({ hasText: 
'Trash' });
-        await trashFolder.hover();
-
-        await expect(page.locator('.folder .operation 
a[nztooltiptitle*="Restore all"]')).toBeVisible();
-        await expect(page.locator('.folder .operation a[nztooltiptitle*="Empty 
all"]')).toBeVisible();
-      }
+      const trashFolder = page.locator('.node .folder').filter({ hasText: 
'Trash' });
+      await trashFolder.hover();
+      await trashFolder.locator('.operation').waitFor({ state: 'visible' });
+
+      // Scoped to trashFolder: same CSS hover rule applies to .node:hover for 
folder nodes
+      await expect(trashFolder.locator('.operation a[nztooltiptitle*="Restore 
all"]')).toBeVisible();
+      await expect(trashFolder.locator('.operation a[nztooltiptitle*="Empty 
all"]')).toBeVisible();
     });
 
     test('When restore all is clicked Then should show confirmation dialog', 
async ({ page }) => {
-      const trashExists = await page
-        .locator('.node .folder')
-        .filter({ hasText: 'Trash' })
-        .isVisible()
-        .catch(() => false);
-
-      if (trashExists) {
-        const trashFolder = page.locator('.node .folder').filter({ hasText: 
'Trash' });
-        await trashFolder.hover();
-
-        const restoreButton = page.locator('.folder .operation 
a[nztooltiptitle*="Restore all"]').first();
-        await expect(restoreButton).toBeVisible();
-        await restoreButton.click();
-
-        await expect(
-          page.locator('text=Folders and notes in the trash will be merged 
into their original position.')
-        ).toBeVisible();
-      }
+      const trashFolder = page.locator('.node .folder').filter({ hasText: 
'Trash' });
+      await trashFolder.hover();
+      await trashFolder.locator('.operation').waitFor({ state: 'visible' });
+
+      const restoreButton = trashFolder.locator('.operation 
a[nztooltiptitle*="Restore all"]');
+      await expect(restoreButton).toBeVisible();
+      // JUSTIFIED: hovering restoreButton directly can briefly exit 
.folder:hover and hide it
+      await restoreButton.click({ force: true });
+
+      await expect(
+        page.locator('text=Folders and notes in the trash will be merged into 
their original position.')
+      ).toBeVisible();
     });
 
     test('When empty trash is clicked Then should show permanent deletion 
warning', async ({ page }) => {
-      const trashExists = await page
-        .locator('.node .folder')
-        .filter({ hasText: 'Trash' })
-        .isVisible()
-        .catch(() => false);
+      const trashFolder = page.locator('.node .folder').filter({ hasText: 
'Trash' });
+      await trashFolder.hover();
+      await trashFolder.locator('.operation').waitFor({ state: 'visible' });
 
-      if (trashExists) {
-        const trashFolder = page.locator('.node .folder').filter({ hasText: 
'Trash' });
-        await trashFolder.hover();
+      const emptyButton = trashFolder.locator('.operation 
a[nztooltiptitle*="Empty all"]');
+      await expect(emptyButton).toBeVisible();
+      await emptyButton.hover();
+      await emptyButton.click();
 
-        const emptyButton = page.locator('.folder .operation 
a[nztooltiptitle*="Empty all"]').first();
-        await expect(emptyButton).toBeVisible();
-        await emptyButton.click();
-
-        await expect(page.locator('text=This cannot be undone. Are you 
sure?')).toBeVisible();
-      }
+      await expect(page.locator('text=This cannot be undone. Are you 
sure?')).toBeVisible();
     });
   });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/home/home-page-notebook-actions.spec.ts 
b/zeppelin-web-angular/e2e/tests/home/home-page-notebook-actions.spec.ts
index 3cb9725dcb..c14a5474e2 100644
--- a/zeppelin-web-angular/e2e/tests/home/home-page-notebook-actions.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/home/home-page-notebook-actions.spec.ts
@@ -27,14 +27,7 @@ test.describe('Home Page Notebook Actions', () => {
   });
 
   test.describe('Given notebook list is displayed', () => {
-    test('When page loads Then should show notebook actions', async () => {
-      await expect(homePage.nodeList.createNewNoteLink).toBeVisible();
-      await expect(homePage.nodeList.importNoteLink).toBeVisible();
-      await expect(homePage.nodeList.filterInput).toBeVisible();
-      await expect(homePage.nodeList.tree).toBeVisible();
-    });
-
-    test('When refresh button is clicked Then should trigger reload with 
loading state', async ({ page }) => {
+    test('When refresh button is clicked Then should keep refresh icon 
visible', async ({ page }) => {
       const refreshButton = page.locator('a.refresh-note');
       const refreshIcon = page.locator('a.refresh-note i[nz-icon]');
 
@@ -42,48 +35,36 @@ test.describe('Home Page Notebook Actions', () => {
       await expect(refreshIcon).toBeVisible();
 
       await homePage.clickRefreshNotes();
-
-      await page.waitForTimeout(500);
+      await homePage.waitForRefreshToComplete();
 
       await expect(refreshIcon).toBeVisible();
     });
 
     test('When filter is used Then should filter notebook list', async ({ page 
}) => {
-      // Note (ZEPPELIN-6386):
-      // The Notebook search filter in the New UI is currently too slow,
-      // so this test is temporarily skipped. The skip will be removed
-      // once the performance issue is resolved.
-      test.skip();
+      test.skip(true, 'ZEPPELIN-6386: Notebook search filter in the New UI is 
too slow — re-enable when fixed');
       await homePage.filterNotes('test');
       await page.waitForLoadState('networkidle', { timeout: 15000 });
       const filteredResults = await page.locator('nz-tree .node').count();
-      expect(filteredResults).toBeGreaterThanOrEqual(0);
+      expect(filteredResults).toBeGreaterThan(0);
     });
-  });
 
-  test.describe('Given create new note action', () => {
-    test('When create new note is clicked Then should open note creation 
modal', async ({ page }) => {
-      await homePage.clickCreateNewNote();
-      await page.waitForSelector('zeppelin-note-create', { timeout: 10000 });
-      await expect(page.locator('zeppelin-note-create')).toBeVisible();
-    });
-  });
+    test('When filter input receives special characters Then page should not 
crash', async ({ page }) => {
+      // Given: The filter input is visible
+      await expect(homePage.nodeList.filterInput).toBeVisible();
 
-  test.describe('Given import note action', () => {
-    test('When import note is clicked Then should open import modal', async ({ 
page }) => {
-      await homePage.clickImportNote();
-      await page.waitForSelector('zeppelin-note-import', { timeout: 10000 });
-      await expect(page.locator('zeppelin-note-import')).toBeVisible();
-    });
-  });
+      // When: User types special characters that could break regex or URL 
encoding
+      for (const specialInput of ['[test]', '*.note', '/folder/sub', 'a?b=c']) 
{
+        await homePage.nodeList.filterInput.fill(specialInput);
+        // Then: The page must still render without crashing — no blank 
screen, input remains editable.
+        // Note: nz-tree may be hidden when the filter returns 0 results; that 
is valid behavior.
+        await expect(page.locator('zeppelin-node-list')).toBeVisible();
+        await expect(homePage.nodeList.filterInput).toBeEditable();
+        await expect(homePage.nodeList.filterInput).toHaveValue(specialInput);
+        await expect(page.locator('zeppelin-header')).toBeVisible();
+      }
 
-  test.describe('Given notebook refresh functionality', () => {
-    test('When refresh is triggered Then should maintain notebook list 
visibility', async () => {
-      await homePage.clickRefreshNotes();
-      await homePage.waitForRefreshToComplete();
-      await expect(homePage.zeppelinNodeList).toBeVisible();
-      const isStillVisible = await homePage.zeppelinNodeList.isVisible();
-      expect(isStillVisible).toBe(true);
+      // Clean up: clear the filter so other tests start fresh
+      await homePage.nodeList.filterInput.fill('');
     });
   });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/notebook/published/published-paragraph.spec.ts 
b/zeppelin-web-angular/e2e/tests/notebook/published/published-paragraph.spec.ts
index b15facedc7..475da43f3b 100644
--- 
a/zeppelin-web-angular/e2e/tests/notebook/published/published-paragraph.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/notebook/published/published-paragraph.spec.ts
@@ -51,6 +51,7 @@ test.describe('Published Paragraph', () => {
 
       await 
publishedParagraphPage.navigateToPublishedParagraph(nonExistentIds.noteId, 
nonExistentIds.paragraphId);
 
+      // JUSTIFIED: last() handles stacked modals where the most recent error 
modal appears on top
       const modal = page.locator('.ant-modal', { hasText: /not found/i 
}).last();
       await expect(modal).toBeVisible({ timeout: 10000 });
       await expect(modal).toContainText(/not found/i);
@@ -77,7 +78,7 @@ test.describe('Published Paragraph', () => {
       await 
publishedParagraphPage.navigateToPublishedParagraph(nonExistentIds.noteId, 
nonExistentIds.paragraphId);
 
       // Modal must appear — we navigated to non-existent IDs
-      const modal = page.locator('.ant-modal').last();
+      const modal = page.locator('.ant-modal').filter({ hasText: /not found/i 
});
       await expect(modal).toBeVisible({ timeout: 10000 });
 
       await publishedParagraphPage.okButton.click();
@@ -93,7 +94,7 @@ test.describe('Published Paragraph', () => {
       await page.goto(`/#/notebook/${noteId}`);
       await page.waitForLoadState('networkidle');
 
-      // createTestNotebook creates a single paragraph, so .first() is the 
target
+      // JUSTIFIED: createTestNotebook creates a single paragraph; first() is 
deterministic
       const paragraphElement = 
page.locator('zeppelin-notebook-paragraph').first();
       await expect(paragraphElement).toBeVisible({ timeout: 10000 });
 
@@ -115,11 +116,19 @@ test.describe('Published Paragraph', () => {
 
     test('should load published paragraph component by direct URL navigation', 
async ({ page }) => {
       await 
page.goto(`/#/notebook/${testNotebook.noteId}/paragraph/${testNotebook.paragraphId}`);
-      await page.waitForLoadState('networkidle');
+
+      // Wait for the confirmation modal — it signals NOTE was received and 
the component is fully rendered.
+      // networkidle fires before the NOTE WebSocket response, so the modal is 
the reliable ready signal.
+      const confirmModal = page.locator('.ant-modal-confirm');
+      await expect(confirmModal).toBeVisible({ timeout: 15000 });
+      await publishedParagraphPage.cancelButton.click();
+      await expect(confirmModal).toBeHidden({ timeout: 5000 });
 
       await expect(page).toHaveURL(
         new 
RegExp(`/notebook/${testNotebook.noteId}/paragraph/${testNotebook.paragraphId}`)
       );
+      // JUSTIFIED: paragraph has no results yet so the component renders 0×0 
— toBeAttached confirms
+      // the route is active without requiring visible content.
       await expect(page.locator('zeppelin-publish-paragraph')).toBeAttached({ 
timeout: 10000 });
     });
 
@@ -127,19 +136,17 @@ test.describe('Published Paragraph', () => {
       const { noteId, paragraphId } = testNotebook;
 
       await page.goto(`/#/notebook/${noteId}/paragraph/${paragraphId}`);
-      await page.waitForLoadState('networkidle');
 
-      const publishedContainer = page.locator('zeppelin-publish-paragraph');
-      await expect(publishedContainer).toBeAttached({ timeout: 10000 });
-
-      // Confirmation modal should appear for paragraph execution
+      // Confirmation modal signals NOTE was received and component is fully 
rendered.
       const modal = page.locator('.ant-modal');
       await expect(modal).toBeVisible({ timeout: 20000 });
 
       await publishedParagraphPage.runButton.click();
       await expect(modal).not.toBeVisible({ timeout: 10000 });
 
-      // Published container should remain attached after modal dismissal
+      const publishedContainer = page.locator('zeppelin-publish-paragraph');
+      // JUSTIFIED: paragraph has no results yet so the component renders 0×0 
— toBeAttached confirms
+      // the route is still active (not navigated away) without requiring 
visible content.
       await expect(publishedContainer).toBeAttached({ timeout: 10000 });
     });
 
@@ -156,6 +163,7 @@ test.describe('Published Paragraph', () => {
       await test.step('And React widget should be mounted in the container', 
async () => {
         // React mount() renders <div data-testid="react-published-paragraph"> 
or <Empty> (Alert)
         const reactContent = 
page.locator('[data-testid="react-published-paragraph"], .ant-alert');
+        // JUSTIFIED: compound selector covers React success + error fallback 
(.ant-alert); either may render
         await expect(reactContent).toBeAttached({ timeout: 15000 });
       });
     });
@@ -166,8 +174,15 @@ test.describe('Published Paragraph', () => {
       const { noteId, paragraphId } = testNotebook;
 
       await page.goto(`/#/notebook/${noteId}/paragraph/${paragraphId}`);
-      await page.waitForLoadState('networkidle');
 
+      // Wait for modal then dismiss — component visibility is unreliable 
while modal is animating open.
+      const confirmModal = page.locator('.ant-modal-confirm');
+      await expect(confirmModal).toBeVisible({ timeout: 15000 });
+      await publishedParagraphPage.cancelButton.click();
+      await expect(confirmModal).toBeHidden({ timeout: 5000 });
+
+      // JUSTIFIED: paragraph has no results yet so the component renders 0×0 
— toBeAttached confirms
+      // the route is active without requiring visible content.
       await expect(page.locator('zeppelin-publish-paragraph')).toBeAttached({ 
timeout: 10000 });
       await 
expect(page.locator('zeppelin-notebook-paragraph-code-editor')).toBeHidden();
       await 
expect(page.locator('zeppelin-notebook-paragraph-control')).toBeHidden();
@@ -175,59 +190,26 @@ test.describe('Published Paragraph', () => {
   });
 
   test.describe('Confirmation Modal and Execution', () => {
-    test('should show confirmation modal with code preview and allow running', 
async ({ page }) => {
-      const { noteId, paragraphId } = testNotebook;
-
-      await publishedParagraphPage.navigateToNotebook(noteId);
-
-      // Verify paragraph has no results yet
-      const paragraphElement = 
page.locator('zeppelin-notebook-paragraph').first();
-      await 
expect(paragraphElement.locator('zeppelin-notebook-paragraph-result')).toBeHidden();
-
-      await publishedParagraphPage.navigateToPublishedParagraph(noteId, 
paragraphId);
-
-      await expect(page).toHaveURL(new RegExp(`/paragraph/${paragraphId}`));
+    for (const reactMode of [false, true]) {
+      test(`should show confirmation modal with code preview and allow 
running${reactMode ? ' (React mode)' : ''}`, async ({
+        page
+      }) => {
+        const { noteId, paragraphId } = testNotebook;
 
-      const modal = publishedParagraphPage.confirmationModal;
-      await expect(modal).toBeVisible();
-
-      // Modal title
-      await expect(publishedParagraphPage.modalTitle).toHaveText('Run 
Paragraph?');
-
-      // Code preview content
-      const modalContent = modal.locator('.ant-modal-confirm-content');
-      await expect(modalContent).toContainText('This paragraph contains the 
following code:');
-      await expect(modalContent).toContainText('Would you like to execute this 
code?');
-
-      // Code preview element
-      const codePreview = modalContent.locator('pre, code, .code-preview, 
[class*="code"]').first();
-      await expect(codePreview).toBeVisible();
-
-      // Run and Cancel buttons
-      await expect(publishedParagraphPage.runButton).toBeVisible();
-      await expect(publishedParagraphPage.cancelButton).toBeVisible();
-
-      // Execute and verify modal dismissal
-      await publishedParagraphPage.runButton.click();
-      await expect(modal).toBeHidden();
-    });
-
-    test('should show confirmation modal in React mode and allow running', 
async ({ page }) => {
-      const { noteId, paragraphId } = testNotebook;
-
-      await test.step('Given paragraph has no results in normal notebook 
view', async () => {
         await publishedParagraphPage.navigateToNotebook(noteId);
 
+        // JUSTIFIED: createTestNotebook creates a single paragraph; first() 
is deterministic
         const paragraphElement = 
page.locator('zeppelin-notebook-paragraph').first();
         await 
expect(paragraphElement.locator('zeppelin-notebook-paragraph-result')).toBeHidden();
-      });
 
-      await test.step('When I navigate to React mode published paragraph URL', 
async () => {
-        await 
page.goto(`/#/notebook/${noteId}/paragraph/${paragraphId}?react=true`);
+        const urlSuffix = reactMode ? '?react=true' : '';
+        await 
page.goto(`/#/notebook/${noteId}/paragraph/${paragraphId}${urlSuffix}`);
         await waitForZeppelinReady(page);
-      });
 
-      await test.step('Then confirmation modal should appear and allow 
execution', async () => {
+        if (!reactMode) {
+          await expect(page).toHaveURL(new 
RegExp(`/paragraph/${paragraphId}`));
+        }
+
         const modal = publishedParagraphPage.confirmationModal;
         await expect(modal).toBeVisible({ timeout: 30000 });
 
@@ -237,9 +219,20 @@ test.describe('Published Paragraph', () => {
         await expect(modalContent).toContainText('This paragraph contains the 
following code:');
         await expect(modalContent).toContainText('Would you like to execute 
this code?');
 
+        if (!reactMode) {
+          // Code preview element only checked in Angular mode
+          // JUSTIFIED: compound fallback selector; first() picks any element 
that confirms code preview is rendered
+          const codePreview = modalContent.locator('pre, code, .code-preview, 
[class*="code"]').first();
+          await expect(codePreview).toBeVisible();
+          await expect(codePreview).not.toBeEmpty(); // code must have 
content, not just an empty container
+
+          await expect(publishedParagraphPage.runButton).toBeVisible();
+          await expect(publishedParagraphPage.cancelButton).toBeVisible();
+        }
+
         await publishedParagraphPage.runButton.click();
         await expect(modal).toBeHidden();
       });
-    });
+    }
   });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/share/about-zeppelin/about-zeppelin-modal.spec.ts
 
b/zeppelin-web-angular/e2e/tests/share/about-zeppelin/about-zeppelin-modal.spec.ts
index 2e8ab234a7..1f2d6fed08 100644
--- 
a/zeppelin-web-angular/e2e/tests/share/about-zeppelin/about-zeppelin-modal.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/share/about-zeppelin/about-zeppelin-modal.spec.ts
@@ -35,18 +35,17 @@ test.describe('About Zeppelin Modal', () => {
 
   test('Given user clicks About Zeppelin menu item, When modal opens, Then 
modal should display all required elements', async () => {
     await expect(aboutModal.modal).toBeVisible();
-    await expect(aboutModal.modalTitle).toBeVisible();
-    await expect(aboutModal.heading).toBeVisible();
+    await expect(aboutModal.modalTitle).toContainText('About Zeppelin');
+    await expect(aboutModal.heading).toContainText('Apache Zeppelin');
     await expect(aboutModal.logo).toBeVisible();
-    await expect(aboutModal.versionText).toBeVisible();
+    await expect(aboutModal.versionText).not.toBeEmpty();
     await expect(aboutModal.getInvolvedLink).toBeVisible();
     await expect(aboutModal.licenseLink).toBeVisible();
   });
 
   test('Given About Zeppelin modal is open, When viewing version information, 
Then version should be displayed', async () => {
     const version = await aboutModal.getVersionText();
-    expect(version).toBeTruthy();
-    expect(version.length).toBeGreaterThan(0);
+    expect(version).toMatch(/\d+\.\d+/);
   });
 
   test('Given About Zeppelin modal is open, When checking external links, Then 
links should have correct URLs', async () => {
@@ -62,8 +61,11 @@ test.describe('About Zeppelin Modal', () => {
     await expect(aboutModal.modal).not.toBeVisible();
   });
 
-  test('Given About Zeppelin modal is open, When checking logo, Then logo 
should be visible and properly loaded', async () => {
-    const isLogoVisible = await aboutModal.isLogoVisible();
-    expect(isLogoVisible).toBe(true);
+  test('Given About Zeppelin modal is open, When checking logo, Then logo 
should be visible and its image loaded', async () => {
+    await expect(aboutModal.logo).toBeVisible();
+    // JUSTIFIED: naturalWidth is the only reliable way to verify image has 
loaded;
+    // Playwright has no built-in assertion for image load status
+    const naturalWidth = await aboutModal.logo.evaluate((img: 
HTMLImageElement) => img.naturalWidth);
+    expect(naturalWidth).toBeGreaterThan(0);
   });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/share/node-list/node-list-functionality.spec.ts
 
b/zeppelin-web-angular/e2e/tests/share/node-list/node-list-functionality.spec.ts
index 111d01011f..2ef30aa82f 100644
--- 
a/zeppelin-web-angular/e2e/tests/share/node-list/node-list-functionality.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/share/node-list/node-list-functionality.spec.ts
@@ -31,16 +31,20 @@ test.describe('Node List Functionality', () => {
   test('Given user is on home page, When viewing node list, Then node list 
should display tree structure', async () => {
     await expect(nodeListPage.nodeListContainer).toBeVisible();
     await expect(nodeListPage.treeView).toBeVisible();
+    // JUSTIFIED: first() confirms at least one tree node is rendered in the 
list
+    await 
expect(nodeListPage.treeView.locator('nz-tree-node').first()).toBeVisible();
   });
 
   test('Given user is on home page, When viewing node list, Then action 
buttons should be visible', async () => {
     await expect(nodeListPage.createNewNoteButton).toBeVisible();
+    await expect(nodeListPage.createNewNoteButton).toContainText('Create new 
Note');
     await expect(nodeListPage.importNoteButton).toBeVisible();
+    await expect(nodeListPage.importNoteButton).toContainText('Import Note');
   });
 
-  test('Given user is on home page, When viewing node list, Then filter input 
should be visible', async () => {
-    const isFilterVisible = await nodeListPage.isFilterInputVisible();
-    expect(isFilterVisible).toBe(true);
+  test('Given user is on home page, When viewing node list, Then filter input 
should be visible with placeholder', async () => {
+    await expect(nodeListPage.filterInput).toBeVisible();
+    await expect(nodeListPage.filterInput).toHaveAttribute('placeholder', 
/[Ff]ilter/);
   });
 
   test('Given a note has been moved to trash, When viewing node list, Then 
trash folder should be visible', async ({
@@ -71,24 +75,28 @@ test.describe('Node List Functionality', () => {
 
     // Wait for the trash folder to appear and verify
     await expect(nodeListPage.trashFolder).toBeVisible({ timeout: 10000 });
-    const isTrashVisible = await nodeListPage.isTrashFolderVisible();
-    expect(isTrashVisible).toBe(true);
   });
 
   test('Given there are notes in node list, When clicking a note, Then user 
should navigate to that note', async ({
     page
   }) => {
-    await expect(nodeListPage.treeView).toBeVisible();
-    const notes = await nodeListPage.getAllVisibleNoteNames();
-
-    if (notes.length > 0 && notes[0]) {
-      const noteName = notes[0].trim();
-
-      await nodeListPage.clickNote(noteName);
-      await page.waitForURL(/notebook\//);
+    const homePage = new HomePage(page);
 
-      expect(page.url()).toContain('notebook/');
+    await expect(nodeListPage.treeView).toBeVisible();
+    let notes = await nodeListPage.getAllVisibleNoteNames();
+
+    if (notes.length === 0) {
+      // Seed a note so the test always runs — critical navigation path must 
not be skipped
+      await homePage.createNote(`_e2e_nav_${Date.now()}`);
+      await page.goto('/');
+      await waitForZeppelinReady(page);
+      notes = await nodeListPage.getAllVisibleNoteNames();
     }
+
+    const noteName = notes[0].trim();
+    await nodeListPage.clickNote(noteName);
+    await page.waitForURL(/notebook\//);
+    expect(page.url()).toContain('notebook/');
   });
 
   test('Given user clicks Create New Note button, When modal opens, Then note 
create modal should be displayed', async ({
diff --git 
a/zeppelin-web-angular/e2e/tests/share/note-create/note-create-modal.spec.ts 
b/zeppelin-web-angular/e2e/tests/share/note-create/note-create-modal.spec.ts
index a2674b4c4a..640e60899c 100644
--- a/zeppelin-web-angular/e2e/tests/share/note-create/note-create-modal.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/share/note-create/note-create-modal.spec.ts
@@ -60,12 +60,13 @@ test.describe('Note Create Modal', () => {
     expect(page.url()).toContain('notebook/');
 
     // Verify the note was created with the correct name
-    const notebookTitle = page.locator('p, .notebook-title, .note-title, h1, 
[data-testid="notebook-title"]').first();
+    const notebookTitle = page.locator('[data-testid="notebook-title"]');
     await expect(notebookTitle).toContainText(uniqueName);
 
     // Verify in the navigation tree if available
-    await page.goto('/');
-    await page.waitForLoadState('networkidle');
+    await page.goto('/#/');
+    await waitForZeppelinReady(page);
+    await page.locator('zeppelin-node-list').waitFor({ state: 'visible', 
timeout: 15000 });
     const noteInTree = page.getByRole('link', { name: uniqueName });
     await expect(noteInTree).toBeVisible();
   });
@@ -87,14 +88,14 @@ test.describe('Note Create Modal', () => {
     expect(page.url()).toContain('notebook/');
 
     // Verify the note was created with the correct name (without folder path)
-    const notebookTitle = page.locator('p, .notebook-title, .note-title, h1, 
[data-testid="notebook-title"]').first();
+    const notebookTitle = page.locator('[data-testid="notebook-title"]');
     await expect(notebookTitle).toContainText(noteName);
 
     // Verify the folder structure was created
-    await page.goto('/');
-    await page.waitForLoadState('networkidle');
-    const folder = page.locator('nz-tree-node').filter({ hasText: 'TestFolder' 
});
-    await expect(folder).toBeVisible();
+    await page.goto('/#/');
+    await waitForZeppelinReady(page);
+    await page.locator('zeppelin-node-list').waitFor({ state: 'visible', 
timeout: 15000 });
+    await 
expect(page.locator('a.name[data-testid="folder-TestFolder"]')).toBeVisible();
   });
 
   test('Given Create Note modal is open, When clicking close button, Then 
modal should close', async () => {
@@ -102,7 +103,7 @@ test.describe('Note Create Modal', () => {
   });
 
   test('Given Create Note modal is open, When viewing folder info alert, Then 
alert should contain folder creation instructions', async () => {
-    const isInfoVisible = await noteCreateModal.isFolderInfoVisible();
-    expect(isInfoVisible).toBe(true);
+    await expect(noteCreateModal.folderInfoAlert).toBeVisible();
+    await expect(noteCreateModal.folderInfoAlert).toContainText("Use '/' to 
create folders");
   });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/share/note-import/note-import-modal.spec.ts 
b/zeppelin-web-angular/e2e/tests/share/note-import/note-import-modal.spec.ts
index b20bee0902..2100d56a39 100644
--- a/zeppelin-web-angular/e2e/tests/share/note-import/note-import-modal.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/share/note-import/note-import-modal.spec.ts
@@ -42,8 +42,7 @@ test.describe('Note Import Modal', () => {
   });
 
   test('Given Import Note modal is open, When viewing default tab, Then JSON 
File tab should be selected', async () => {
-    const isJsonTabSelected = await noteImportModal.isJsonFileTabSelected();
-    expect(isJsonTabSelected).toBe(true);
+    await expect(noteImportModal.jsonFileTab).toHaveAttribute('aria-selected', 
'true');
 
     await expect(noteImportModal.uploadArea).toBeVisible();
     await expect(noteImportModal.uploadText).toBeVisible();
@@ -52,8 +51,7 @@ test.describe('Note Import Modal', () => {
   test('Given Import Note modal is open, When switching to URL tab, Then URL 
input should be visible', async () => {
     await noteImportModal.switchToUrlTab();
 
-    const isUrlTabSelected = await noteImportModal.isUrlTabSelected();
-    expect(isUrlTabSelected).toBe(true);
+    await expect(noteImportModal.urlTab).toHaveAttribute('aria-selected', 
'true');
 
     await expect(noteImportModal.urlInput).toBeVisible();
     await expect(noteImportModal.importNoteButton).toBeVisible();
@@ -62,16 +60,14 @@ test.describe('Note Import Modal', () => {
   test('Given URL tab is selected, When URL is empty, Then import button 
should be disabled', async () => {
     await noteImportModal.switchToUrlTab();
 
-    const isDisabled = await noteImportModal.isImportNoteButtonDisabled();
-    expect(isDisabled).toBe(true);
+    await expect(noteImportModal.importNoteButton).toBeDisabled();
   });
 
   test('Given URL tab is selected, When entering URL, Then import button 
should be enabled', async () => {
     await noteImportModal.switchToUrlTab();
     await noteImportModal.setImportUrl('https://example.com/note.json');
 
-    const isDisabled = await noteImportModal.isImportNoteButtonDisabled();
-    expect(isDisabled).toBe(false);
+    await expect(noteImportModal.importNoteButton).toBeEnabled();
   });
 
   test('Given Import Note modal is open, When entering import name, Then name 
should be set', async () => {
@@ -84,8 +80,7 @@ test.describe('Note Import Modal', () => {
 
   test('Given JSON File tab is selected, When viewing file size limit, Then 
limit should be displayed', async () => {
     const fileSizeLimit = await noteImportModal.getFileSizeLimit();
-    expect(fileSizeLimit).toBeTruthy();
-    expect(fileSizeLimit.length).toBeGreaterThan(0);
+    expect(fileSizeLimit).toMatch(/\d+\s*(MB|KB|GB)/i);
   });
 
   test('Given Import Note modal is open, When clicking close button, Then 
modal should close', async () => {
@@ -99,7 +94,6 @@ test.describe('Note Import Modal', () => {
     await noteImportModal.clickImportNote();
 
     await expect(noteImportModal.errorAlert).toBeVisible();
-    const errorMessage = await noteImportModal.getErrorMessage();
-    expect(errorMessage).toBeTruthy();
+    await expect(noteImportModal.errorAlert).not.toBeEmpty();
   });
 });
diff --git a/zeppelin-web-angular/e2e/tests/theme/dark-mode.spec.ts 
b/zeppelin-web-angular/e2e/tests/theme/dark-mode.spec.ts
index 61a15e26d1..13b03fbdd3 100644
--- a/zeppelin-web-angular/e2e/tests/theme/dark-mode.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/theme/dark-mode.spec.ts
@@ -34,16 +34,15 @@ test.describe('Dark Mode Theme Switching', () => {
     await darkModePage.clearLocalStorage();
   });
 
-  test('Scenario: User can switch to dark mode and persistence is maintained', 
async ({ page, browserName }) => {
+  test('Scenario: Dark mode persists across page reload when set via 
localStorage', 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 darkModePage.assertSystemTheme(); // Robot icon for system theme
     });
 
-    // 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 
() => {
+    // WHEN: Set theme to light via localStorage and reload (bypasses UI 
toggle for test setup).
+    await test.step('WHEN localStorage theme is set to light and page 
reloads', async () => {
       await darkModePage.setThemeInLocalStorage('light');
-      await page.waitForTimeout(500);
       // Reload the page to apply localStorage theme changes
       if (browserName === 'webkit') {
         const currentUrl = page.url();
@@ -55,10 +54,9 @@ test.describe('Dark Mode Theme Switching', () => {
       await darkModePage.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 explicitly sets theme to dark mode', async 
() => {
+    // WHEN: Set theme to dark via localStorage and reload.
+    await test.step('WHEN localStorage theme is set to dark and page reloads', 
async () => {
       await darkModePage.setThemeInLocalStorage('dark');
-      await page.waitForTimeout(500);
       // Reload the page to apply localStorage theme changes
       if (browserName === 'webkit') {
         const currentUrl = page.url();
diff --git 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-display.spec.ts
 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-display.spec.ts
index 6e887b1924..1796e1578a 100644
--- 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-display.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-display.spec.ts
@@ -28,8 +28,10 @@ test.describe('Notebook Repository Item - Display Mode', () 
=> {
     notebookReposPage = new NotebookReposPage(page);
     await notebookReposPage.navigate();
 
+    // JUSTIFIED: .first() picks the first configured repo; tests require at 
least one repo to be present
     const firstCard = notebookReposPage.repositoryItems.first();
     firstRepoName = (await 
firstCard.locator('.ant-card-head-title').textContent()) || '';
+    expect(firstRepoName, 'No repository found — ensure at least one repo is 
configured').not.toBe('');
     repoItemPage = new NotebookRepoItemPage(page, firstRepoName);
   });
 
@@ -40,14 +42,7 @@ test.describe('Notebook Repository Item - Display Mode', () 
=> {
 
   test('should show edit button in display mode', async () => {
     await expect(repoItemPage.editButton).toBeVisible();
-  });
-
-  test('should display settings table', async () => {
-    await expect(repoItemPage.settingTable).toBeVisible();
-  });
-
-  test('should show all settings in display mode', async () => {
-    const settingCount = await repoItemPage.getSettingCount();
-    expect(settingCount).toBeGreaterThan(0);
+    await expect(repoItemPage.editButton).toBeEnabled();
+    await expect(repoItemPage.editButton).toContainText('Edit');
   });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-edit.spec.ts
 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-edit.spec.ts
index 1ee350c21d..5fd6af53b9 100644
--- 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-edit.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-edit.spec.ts
@@ -30,8 +30,10 @@ test.describe('Notebook Repository Item - Edit Mode', () => {
     notebookReposPage = new NotebookReposPage(page);
     await notebookReposPage.navigate();
 
+    // JUSTIFIED: .first() picks the first configured repo; tests require at 
least one repo to be present
     const firstCard = notebookReposPage.repositoryItems.first();
     firstRepoName = (await 
firstCard.locator('.ant-card-head-title').textContent()) || '';
+    expect(firstRepoName, 'No repository found — ensure at least one repo is 
configured').not.toBe('');
     repoItemPage = new NotebookRepoItemPage(page, firstRepoName);
     repoItemUtil = new NotebookRepoItemUtil(page, firstRepoName);
   });
@@ -41,42 +43,8 @@ test.describe('Notebook Repository Item - Edit Mode', () => {
     await repoItemUtil.verifyEditMode();
   });
 
-  test('should show save and cancel buttons in edit mode', async () => {
-    await repoItemPage.clickEdit();
-    await expect(repoItemPage.saveButton).toBeVisible();
-    await expect(repoItemPage.cancelButton).toBeVisible();
-  });
-
   test('should hide edit button in edit mode', async () => {
     await repoItemPage.clickEdit();
     await expect(repoItemPage.editButton).toBeHidden();
   });
-
-  test('should apply edit CSS class to card in edit mode', async () => {
-    await repoItemPage.clickEdit();
-    const isEditMode = await repoItemPage.isEditMode();
-    expect(isEditMode).toBe(true);
-  });
-
-  test('should exit edit mode when cancel button is clicked', async () => {
-    await repoItemPage.clickEdit();
-    await repoItemUtil.verifyEditMode();
-    await repoItemPage.clickCancel();
-    await repoItemUtil.verifyDisplayMode();
-  });
-
-  test('should reset form when cancel is clicked', async () => {
-    const firstRow = repoItemPage.settingRows.first();
-    const settingName = (await firstRow.locator('td').first().textContent()) 
|| '';
-    const originalValue = await repoItemPage.getSettingValue(settingName);
-
-    await repoItemPage.clickEdit();
-
-    await repoItemPage.fillSettingInput(settingName, 'temp-value');
-
-    await repoItemPage.clickCancel();
-
-    const currentValue = await repoItemPage.getSettingValue(settingName);
-    expect(currentValue.trim()).toBe(originalValue.trim());
-  });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-form-validation.spec.ts
 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-form-validation.spec.ts
index aedf7e1675..e4fc940322 100644
--- 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-form-validation.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-form-validation.spec.ts
@@ -28,55 +28,55 @@ test.describe('Notebook Repository Item - Form Validation', 
() => {
     notebookReposPage = new NotebookReposPage(page);
     await notebookReposPage.navigate();
 
+    // JUSTIFIED: .first() picks the first configured repo; tests require at 
least one repo to be present
     const firstCard = notebookReposPage.repositoryItems.first();
     firstRepoName = (await 
firstCard.locator('.ant-card-head-title').textContent()) || '';
+    expect(firstRepoName, 'No repository found — ensure at least one repo is 
configured').not.toBe('');
     repoItemPage = new NotebookRepoItemPage(page, firstRepoName);
   });
 
   test('should disable save button when form is invalid', async () => {
     await repoItemPage.clickEdit();
 
+    // JUSTIFIED: any row is sufficient — all rows share the same 
save-disable-on-empty behavior
     const firstRow = repoItemPage.settingRows.first();
+    // JUSTIFIED: td.first() is the Name column in the fixed 2-column settings 
table
     const settingName = (await firstRow.locator('td').first().textContent()) 
|| '';
 
     await repoItemPage.fillSettingInput(settingName, '');
 
-    const isSaveEnabled = await repoItemPage.isSaveButtonEnabled();
-    expect(isSaveEnabled).toBe(false);
+    await expect(repoItemPage.saveButton).not.toBeEnabled();
   });
 
   test('should enable save button when form is valid', async () => {
     await repoItemPage.clickEdit();
 
+    // JUSTIFIED: any row is sufficient — all rows share the same 
save-enable-on-valid behavior
     const firstRow = repoItemPage.settingRows.first();
+    // JUSTIFIED: td.first() is the Name column in the fixed 2-column settings 
table
     const settingName = (await firstRow.locator('td').first().textContent()) 
|| '';
 
     const originalValue = await repoItemPage.getSettingInputValue(settingName);
     await repoItemPage.fillSettingInput(settingName, originalValue || 
'valid-value');
 
-    const isSaveEnabled = await repoItemPage.isSaveButtonEnabled();
-    expect(isSaveEnabled).toBe(true);
+    await expect(repoItemPage.saveButton).toBeEnabled();
   });
 
-  test('should validate required fields on form controls', async () => {
+  test('should have editable controls for every setting row in edit mode', 
async () => {
     const settingRows = await repoItemPage.settingRows.count();
 
     await repoItemPage.clickEdit();
 
     for (let i = 0; i < settingRows; i++) {
+      // JUSTIFIED: nth(i) iterates all rows deterministically; order matches 
server-defined settings
       const row = repoItemPage.settingRows.nth(i);
-      const settingName = (await row.locator('td').first().textContent()) || 
'';
-
-      const isInputVisible = await repoItemPage.isInputVisible(settingName);
-      if (isInputVisible) {
-        const input = row.locator('input[nz-input]');
-        await expect(input).toBeVisible();
-      }
-
-      const isDropdownVisible = await 
repoItemPage.isDropdownVisible(settingName);
-      if (isDropdownVisible) {
-        const select = row.locator('nz-select');
-        await expect(select).toBeVisible();
+      const input = row.locator('input[nz-input]');
+      const select = row.locator('nz-select');
+      await expect(input.or(select), `Row ${i} must have an editable control 
in edit mode`).toBeVisible();
+      const isInputRow = await input.isVisible();
+      if (isInputRow) {
+        // JUSTIFIED: attribute check only applies to INPUT-type rows; 
DROPDOWN-type rows use nz-select and have no nz-input
+        await expect(input).toHaveAttribute('nz-input');
       }
     }
   });
diff --git 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-settings.spec.ts
 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-settings.spec.ts
index 68cc608bb3..db65b97063 100644
--- 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-settings.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-settings.spec.ts
@@ -28,8 +28,10 @@ test.describe('Notebook Repository Item - Settings', () => {
     notebookReposPage = new NotebookReposPage(page);
     await notebookReposPage.navigate();
 
+    // JUSTIFIED: .first() picks the first configured repo; tests require at 
least one repo to be present
     const firstCard = notebookReposPage.repositoryItems.first();
     firstRepoName = (await 
firstCard.locator('.ant-card-head-title').textContent()) || '';
+    expect(firstRepoName, 'No repository found — ensure at least one repo is 
configured').not.toBe('');
     repoItemPage = new NotebookRepoItemPage(page, firstRepoName);
   });
 
@@ -37,79 +39,67 @@ test.describe('Notebook Repository Item - Settings', () => {
     await expect(repoItemPage.settingTable).toBeVisible();
 
     const headers = repoItemPage.settingTable.locator('thead th');
-    await expect(headers.nth(0)).toContainText('Name');
-    await expect(headers.nth(1)).toContainText('Value');
+    await expect(headers.filter({ hasText: 'Name' })).toBeVisible();
+    await expect(headers.filter({ hasText: 'Value' })).toBeVisible();
   });
 
-  test('should display all setting rows', async () => {
-    const settingCount = await repoItemPage.getSettingCount();
-    expect(settingCount).toBeGreaterThan(0);
-  });
-
-  test('should show input controls for INPUT type settings in edit mode', 
async () => {
-    const settingRows = await repoItemPage.settingRows.count();
-
+  test('should show input controls for INPUT type settings in edit mode', 
async ({ page }) => {
     await repoItemPage.clickEdit();
 
-    for (let i = 0; i < settingRows; i++) {
-      const row = repoItemPage.settingRows.nth(i);
-      const settingName = (await row.locator('td').first().textContent()) || 
'';
+    const inputRows = repoItemPage.settingRows.filter({ has: 
page.locator('input[nz-input]') });
+    await expect(inputRows).not.toHaveCount(0); // repo must have at least one 
INPUT-type setting
 
-      const isInputVisible = await repoItemPage.isInputVisible(settingName);
-      if (isInputVisible) {
-        const input = row.locator('input[nz-input]');
-        await expect(input).toBeVisible();
-        await expect(input).toHaveAttribute('nz-input');
-      }
+    const count = await inputRows.count();
+    for (let i = 0; i < count; i++) {
+      // JUSTIFIED: nth(i) iterates all INPUT-type rows deterministically; 
order matches server-defined settings
+      const input = inputRows.nth(i).locator('input[nz-input]');
+      await expect(input).toBeVisible();
+      await expect(input).toHaveAttribute('nz-input');
     }
   });
 
-  test('should show dropdown controls for DROPDOWN type settings in edit 
mode', async () => {
-    const settingRows = await repoItemPage.settingRows.count();
-
+  test('should show dropdown controls for DROPDOWN type settings in edit 
mode', async ({ page }) => {
     await repoItemPage.clickEdit();
 
-    for (let i = 0; i < settingRows; i++) {
-      const row = repoItemPage.settingRows.nth(i);
-      const settingName = (await row.locator('td').first().textContent()) || 
'';
+    const dropdownRows = repoItemPage.settingRows.filter({ has: 
page.locator('nz-select') });
+    const count = await dropdownRows.count();
+    test.skip(count === 0, 'VFSNotebookRepo has no DROPDOWN-type settings in 
this environment');
 
-      const isDropdownVisible = await 
repoItemPage.isDropdownVisible(settingName);
-      if (isDropdownVisible) {
-        const select = row.locator('nz-select');
-        await expect(select).toBeVisible();
-      }
+    for (let i = 0; i < count; i++) {
+      // JUSTIFIED: nth(i) iterates all DROPDOWN-type rows deterministically; 
order matches server-defined settings
+      await expect(dropdownRows.nth(i).locator('nz-select')).toBeVisible();
     }
   });
 
-  test('should update input value in edit mode', async () => {
-    const settingRows = await repoItemPage.settingRows.count();
-
+  test('should update input value in edit mode', async ({ page }) => {
     await repoItemPage.clickEdit();
 
-    for (let i = 0; i < settingRows; i++) {
-      const row = repoItemPage.settingRows.nth(i);
-      const settingName = (await row.locator('td').first().textContent()) || 
'';
-
-      const isInputVisible = await repoItemPage.isInputVisible(settingName);
-      if (isInputVisible) {
-        const testValue = 'test-value';
-        await repoItemPage.fillSettingInput(settingName, testValue);
-        const inputValue = await 
repoItemPage.getSettingInputValue(settingName);
-        expect(inputValue).toBe(testValue);
-        break;
-      }
-    }
+    const inputRows = repoItemPage.settingRows.filter({ has: 
page.locator('input[nz-input]') });
+    await expect(inputRows).not.toHaveCount(0); // repo must have at least one 
INPUT-type setting
+
+    // JUSTIFIED: any INPUT-type row works — all share the same input control 
structure
+    const firstRow = inputRows.first();
+    // JUSTIFIED: td.first() is the Name column in the fixed 2-column settings 
table
+    const settingName = (await firstRow.locator('td').first().textContent()) 
|| '';
+    const testValue = 'test-value';
+    await repoItemPage.fillSettingInput(settingName, testValue);
+    expect(await 
repoItemPage.getSettingInputValue(settingName)).toBe(testValue);
   });
 
   test('should display setting name and value in display mode', async () => {
+    // JUSTIFIED: any row is sufficient — testing Name/Value column structure 
shared by all rows
     const firstRow = repoItemPage.settingRows.first();
+    // JUSTIFIED: td.first() = Name column in the fixed 2-column settings table
     const nameCell = firstRow.locator('td').first();
+    // JUSTIFIED: td.nth(1) = Value column in the fixed 2-column settings table
     const valueCell = firstRow.locator('td').nth(1);
 
     await expect(nameCell).toBeVisible();
     await expect(valueCell).toBeVisible();
 
     const nameText = await nameCell.textContent();
-    expect(nameText).toBeTruthy();
+    expect(nameText).not.toBe('');
+    const valueText = await valueCell.textContent();
+    expect(valueText).not.toBe('');
   });
 });
diff --git 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-workflow.spec.ts
 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-workflow.spec.ts
index 52f3e42909..0fd368e493 100644
--- 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-workflow.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repo-item-workflow.spec.ts
@@ -30,6 +30,7 @@ test.describe('Notebook Repository Item - Edit Workflow', () 
=> {
     notebookReposPage = new NotebookReposPage(page);
     await notebookReposPage.navigate();
 
+    // JUSTIFIED: .first() picks the first configured repo; tests require at 
least one repo to be present
     const firstCard = notebookReposPage.repositoryItems.first();
     firstRepoName = (await 
firstCard.locator('.ant-card-head-title').textContent()) || '';
     repoItemPage = new NotebookRepoItemPage(page, firstRepoName);
@@ -44,30 +45,41 @@ test.describe('Notebook Repository Item - Edit Workflow', 
() => {
     await repoItemPage.clickEdit();
     await repoItemUtil.verifyEditMode();
 
+    let savedSettingName = '';
+    let savedValue = '';
     for (let i = 0; i < settingRows; i++) {
+      // JUSTIFIED: nth(i) iterates all rows deterministically to find the 
first INPUT-type row
       const row = repoItemPage.settingRows.nth(i);
+      // JUSTIFIED: td.first() is the Name column in the fixed 2-column 
settings table
       const settingName = (await row.locator('td').first().textContent()) || 
'';
 
-      const isInputVisible = await repoItemPage.isInputVisible(settingName);
+      const isInputVisible = await row.locator('input[nz-input]').isVisible();
       if (isInputVisible) {
-        const originalValue = await 
repoItemPage.getSettingInputValue(settingName);
-        await repoItemPage.fillSettingInput(settingName, originalValue || 
'test-value');
+        savedValue = (await repoItemPage.getSettingInputValue(settingName)) || 
'test-value';
+        await repoItemPage.fillSettingInput(settingName, savedValue);
+        savedSettingName = settingName;
         break;
       }
     }
 
-    const isSaveEnabled = await repoItemPage.isSaveButtonEnabled();
-    expect(isSaveEnabled).toBe(true);
+    expect(savedSettingName, 'No INPUT-type setting found — cannot verify save 
result').not.toBe('');
+    await expect(repoItemPage.saveButton).toBeEnabled();
 
     await repoItemPage.clickSave();
 
     await repoItemUtil.verifyDisplayMode();
+
+    // Verify the saved value is shown in display mode — not just that mode 
switched
+    const displayValue = await repoItemPage.getSettingValue(savedSettingName);
+    expect(displayValue.trim()).toBe(savedValue.trim());
   });
 
   test('should complete full edit workflow with cancel', async () => {
     await repoItemUtil.verifyDisplayMode();
 
+    // JUSTIFIED: any row is representative — testing that cancel reverts all 
changes
     const firstRow = repoItemPage.settingRows.first();
+    // JUSTIFIED: td.first() is the Name column in the fixed 2-column settings 
table
     const settingName = (await firstRow.locator('td').first().textContent()) 
|| '';
     const originalValue = await repoItemPage.getSettingValue(settingName);
 
diff --git 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repos-page-structure.spec.ts
 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repos-page-structure.spec.ts
index 747037ef47..39cccf2c58 100644
--- 
a/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repos-page-structure.spec.ts
+++ 
b/zeppelin-web-angular/e2e/tests/workspace/notebook-repos/notebook-repos-page-structure.spec.ts
@@ -29,16 +29,14 @@ test.describe('Notebook Repository Page - Structure', () => 
{
 
   test('should display page header with correct title and description', async 
() => {
     await expect(notebookReposPage.zeppelinPageHeader).toBeVisible();
-    await expect(notebookReposPage.pageDescription).toBeVisible();
+    await expect(notebookReposPage.zeppelinPageHeader).toContainText('Notebook 
Repository');
+    await expect(notebookReposPage.pageDescription).toContainText("Manage your 
Notebook Repositories' settings.");
   });
 
-  test('should render repository list container', async () => {
-    const count = await notebookReposPage.getRepositoryItemCount();
-    expect(count).toBeGreaterThanOrEqual(0);
-  });
-
-  test('should display all repository items', async () => {
-    const count = await notebookReposPage.getRepositoryItemCount();
-    expect(count).toBeGreaterThan(0);
+  test('should display all repository items with names', async () => {
+    await expect(notebookReposPage.repositoryItems).not.toHaveCount(0);
+    // JUSTIFIED: .first() samples the first repo card; all cards share the 
same title structure
+    const firstTitle = 
notebookReposPage.repositoryItems.first().locator('.ant-card-head-title');
+    await expect(firstTitle).not.toBeEmpty();
   });
 });
diff --git a/zeppelin-web-angular/e2e/tests/workspace/workspace-main.spec.ts 
b/zeppelin-web-angular/e2e/tests/workspace/workspace-main.spec.ts
index a3e42474c0..106345fd2e 100644
--- a/zeppelin-web-angular/e2e/tests/workspace/workspace-main.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/workspace/workspace-main.spec.ts
@@ -11,58 +11,40 @@
  */
 
 import { expect, test } from '@playwright/test';
-import { WorkspacePage } from 'e2e/models/workspace-page';
-import { WorkspaceUtil } from '../../models/workspace-page.util';
+import { BasePage } from 'e2e/models/base-page';
 import { addPageAnnotationBeforeEach, PAGES, performLoginIfRequired, 
waitForZeppelinReady } from '../../utils';
 
 addPageAnnotationBeforeEach(PAGES.WORKSPACE.MAIN);
 
 test.describe('Workspace Main Component', () => {
-  let workspaceUtil: WorkspaceUtil;
-  let workspacePage: WorkspacePage;
+  let basePage: BasePage;
 
   test.beforeEach(async ({ page }) => {
     await page.goto('/#/');
     await waitForZeppelinReady(page);
     await performLoginIfRequired(page);
 
-    workspacePage = new WorkspacePage(page);
-    workspaceUtil = new WorkspaceUtil(page);
+    basePage = new BasePage(page);
   });
 
   test.describe('Given user accesses workspace container', () => {
-    test('When workspace loads Then should display main container structure', 
async ({ page }) => {
-      await expect(workspacePage.zeppelinWorkspace).toBeVisible();
-      await expect(workspacePage.routerOutlet).toBeAttached();
-
-      await expect(workspacePage.zeppelinWorkspace).toBeVisible();
-      const contentElements = await page.locator('.content').count();
-      expect(contentElements).toBeGreaterThan(0);
+    test('When workspace loads Then should display main container structure', 
async () => {
+      await expect(basePage.zeppelinWorkspace).toBeVisible();
+      // Verify workspace contains the header — not just that the elements 
exist in isolation
+      await 
expect(basePage.zeppelinWorkspace.locator('zeppelin-header')).toBeVisible();
     });
 
     test('When workspace loads Then should display header component', async () 
=> {
-      await workspaceUtil.verifyHeaderVisibility(true);
-    });
-
-    test('When workspace loads Then should activate router outlet', async () 
=> {
-      await workspaceUtil.verifyRouterOutletActivation();
-    });
-
-    test('When component activates Then should trigger onActivate event', 
async () => {
-      await workspaceUtil.waitForComponentActivation();
+      await expect(basePage.zeppelinHeader).toBeVisible();
+      // Header must contain navigable content, not just be an empty shell
+      await expect(basePage.zeppelinHeader).toContainText('Zeppelin');
     });
-  });
-
-  test.describe('Given workspace header visibility', () => {
-    test('When not in publish mode Then should show header', async () => {
-      await workspaceUtil.verifyHeaderVisibility(true);
-    });
-  });
 
-  test.describe('Given router outlet functionality', () => {
-    test('When navigating to workspace Then should load child components', 
async () => {
-      await workspaceUtil.verifyRouterOutletActivation();
-      await workspaceUtil.waitForComponentActivation();
+    test('When workspace loads Then should have router outlet attached with 
home component', async ({ page }) => {
+      // Router outlet must have an activated child, not just exist as an 
empty outlet
+      await expect(page.locator('zeppelin-workspace router-outlet + 
*')).toHaveCount(1);
+      // Activated route must have rendered the home component
+      await 
expect(basePage.zeppelinWorkspace.locator('zeppelin-home')).toBeVisible();
     });
   });
 });
diff --git a/zeppelin-web-angular/e2e/utils.ts 
b/zeppelin-web-angular/e2e/utils.ts
index efd6096532..18a66a0ee6 100644
--- a/zeppelin-web-angular/e2e/utils.ts
+++ b/zeppelin-web-angular/e2e/utils.ts
@@ -184,8 +184,6 @@ export const performLoginIfRequired = async (page: Page): 
Promise<boolean> => {
     const loginPage = new LoginPage(page);
     await loginPage.login(testUser.username, testUser.password);
 
-    // for webkit
-    await page.waitForTimeout(200);
     await page.evaluate(() => {
       if (window.location.hash.includes('login')) {
         window.location.hash = '#/';
@@ -220,6 +218,7 @@ export const waitForZeppelinReady = async (page: Page): 
Promise<void> => {
       // If we're on login page, this is expected when authentication is 
required
       // Just wait for login elements to be ready instead of waiting for app 
content
       await page.waitForFunction(
+        // JUSTIFIED: multi-condition AND — Angular presence + login element 
OR across three selectors; can't express as single locator wait
         () => {
           const hasAngular = document.querySelector('[ng-version]') !== null;
           const hasLoginElements =
@@ -236,6 +235,7 @@ export const waitForZeppelinReady = async (page: Page): 
Promise<void> => {
 
     // Wait for Angular and Zeppelin to be ready with more robust checks
     await page.waitForFunction(
+      // JUSTIFIED: multi-condition OR across DOM + textContent checks; 
textContent not expressible via Playwright locator API
       () => {
         // Check for Angular framework
         const hasAngular = document.querySelector('[ng-version]') !== null;
@@ -347,9 +347,7 @@ const navigateViaHomePageFallback = async (page: Page, 
baseNotebookName: string)
   await page.waitForLoadState('networkidle', { timeout: 15000 });
   await page.waitForSelector('zeppelin-node-list', { timeout: 15000 });
 
-  await page.waitForFunction(() => 
document.querySelectorAll(NOTEBOOK_PATTERNS.LINK_SELECTOR).length > 0, {
-    timeout: 15000
-  });
+  await page.locator(NOTEBOOK_PATTERNS.LINK_SELECTOR).first().waitFor({ state: 
'attached', timeout: 15000 });
   await page.waitForLoadState('domcontentloaded', { timeout: 15000 });
 
   const notebookLink = page.locator(NOTEBOOK_PATTERNS.LINK_SELECTOR).filter({ 
hasText: baseNotebookName });
@@ -386,6 +384,10 @@ const extractFirstParagraphId = async (page: Page): 
Promise<string> => {
   await paragraphLink.waitFor({ state: 'attached', timeout: 15000 });
 
   const paragraphId = await paragraphLink.textContent();
+
+  // Close the dropdown before returning — leaving it open leaks state into 
subsequent tests
+  await page.keyboard.press('Escape');
+
   if (!paragraphId || !paragraphId.startsWith('paragraph_')) {
     throw new Error(`Invalid paragraph ID found: ${paragraphId}`);
   }
diff --git a/zeppelin-web-angular/playwright.config.js 
b/zeppelin-web-angular/playwright.config.js
index 6e3e664bf0..06e9270385 100644
--- a/zeppelin-web-angular/playwright.config.js
+++ b/zeppelin-web-angular/playwright.config.js
@@ -20,7 +20,7 @@ module.exports = defineConfig({
   fullyParallel: true,
   forbidOnly: !!process.env.CI,
   retries: process.env.CI ? 2 : 1,
-  workers: process.env.CI ? 2 : 10,
+  workers: process.env.CI ? 2 : 5,
   timeout: 300000,
   expect: {
     timeout: 60000
diff --git a/zeppelin-web-angular/projects/zeppelin-react/package-lock.json 
b/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
index ff9ba13cd0..2fa8a69a4b 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
+++ b/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
@@ -4824,9 +4824,9 @@
       }
     },
     "node_modules/flatted": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz";,
-      "integrity": 
"sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz";,
+      "integrity": 
"sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==",
       "dev": true,
       "license": "ISC"
     },
diff --git 
a/zeppelin-web-angular/src/app/pages/workspace/notebook/action-bar/action-bar.component.html
 
b/zeppelin-web-angular/src/app/pages/workspace/notebook/action-bar/action-bar.component.html
index 8e3bdea00b..54f4e46853 100644
--- 
a/zeppelin-web-angular/src/app/pages/workspace/notebook/action-bar/action-bar.component.html
+++ 
b/zeppelin-web-angular/src/app/pages/workspace/notebook/action-bar/action-bar.component.html
@@ -11,7 +11,7 @@
   -->
 
 <div class="bar" [class.simple]="looknfeel !== 'default'">
-  <div class="title" role="heading" aria-level="1">
+  <div class="title" role="heading" aria-level="1" 
data-testid="notebook-title">
     <zeppelin-elastic-input
       nz-tooltip
       [nzTooltipTitle]="note.path"


Reply via email to