Skip to content

[ZEPPELIN-6527] Fix flaky run-e2e-tests-in-zeppelin-web CI job (searchBlock Protractor timing)#5295

Open
miinhho wants to merge 7 commits into
apache:masterfrom
miinhho:fix/flaky-e2e-in-zeppelin-web
Open

[ZEPPELIN-6527] Fix flaky run-e2e-tests-in-zeppelin-web CI job (searchBlock Protractor timing)#5295
miinhho wants to merge 7 commits into
apache:masterfrom
miinhho:fix/flaky-e2e-in-zeppelin-web

Conversation

@miinhho

@miinhho miinhho commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What is this PR for?

This PR removes the flaky classic zeppelin-web Protractor e2e job by moving its remaining active coverage to the existing Playwright e2e workflow.

The old run-e2e-tests-in-zeppelin-web job depended on Protractor, webdriver-manager, and a pinned ChromeDriver 2.35, and had been failing intermittently in the classic search/replace tests due to AngularJS/Ace synchronization timing.

Since that stack is end-of-life and cannot be reasonably modernized in place, this PR ports the 10 active checks from home.spec.js and searchBlock.spec.js to Playwright, pointed at the classic /classic UI.

The migrated tests keep the existing classic UI coverage for the home page, interpreter permission save flow, search shortcut, match counters, replace, and replace-all behavior. After that coverage is available in Playwright, the obsolete Protractor config, scripts, dependencies, and CI job are removed.

What type of PR is it?

Improvement

What is the Jira issue?

https://issues.apache.org/jira/browse/ZEPPELIN-6527

How should this be tested?

cd zeppelin-web-angular
npx playwright test e2e/tests/classic --project=classic --reporter=line

For the Maven/CI path:

./mvnw clean install -DskipTests -am -pl python,zeppelin-jupyter-interpreter,zeppelin-web,zeppelin-web-angular -Pweb-classic
xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" ./mvnw verify -pl zeppelin-web-angular -Pweb-e2e

Questions:

  • Does the license files need to update? No
  • Is there breaking changes for older versions? No
  • Does this needs documentation? Edit zeppelin-web/README.md to reflect migrated classic web e2e test

miinhho added 4 commits July 13, 2026 21:35
  Move the active classic zeppelin-web e2e coverage from Protractor to
  the
  existing Playwright harness. Add a classic Playwright project for the
  legacy /classic UI, port the active home and search block checks, and
  remove
  the obsolete Protractor/webdriver-manager entry points from
  zeppelin-web.

  Also update the frontend CI job to build the classic UI and run the
  migrated
  checks through zeppelin-web-angular's Playwright e2e flow.

@voidmatcha voidmatcha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work dropping Protractor and moving the classic UI checks to Playwright. The ported cases match the originals closely, and retiring the flaky run-e2e-tests-in-zeppelin-web job is a good cleanup.

A few things I'd tweak. I pushed them as separate commits on my fork so they're easy to cherry-pick or diff against.

  1. Make the base URL overridable via PLAYWRIGHT_BASE_URL. Right now the config computes it into a local variable, so there's no way to point the run elsewhere. Collapsing it to one env var keeps local and CI consistent.
    voidmatcha@7059e995d

  2. Run the classic suite through an e2e:classic script plus E2E_CLASSIC. npm run e2e -- --project=classic leans on fragile classic-only detection, so an explicit env var and npm script make the :8080 run unambiguous.
    voidmatcha@96ce23558

  3. Document the classic conventions in e2e/AGENTS.md: that it's a frozen legacy surface, the locator exceptions the classic templates need, gating readiness on a classic signal instead of waitForZeppelinReady, the coverage exemption, how to run it, and the anonymous-only CI scoping.
    voidmatcha@3b894aaea

  4. Skip the classic project in the auth CI leg. The original Protractor suite only ran anonymous, so scoping classic to the anonymous leg via E2E_MODE matches that.
    voidmatcha@0b5b83309

Full diff: voidmatcha/zeppelin@8597767...review/pr-5295-fixes

One note: the red CI here isn't from your PR. It's the new-UI keyboard-shortcut spec being flaky, and I'm tracking that one separately: https://issues.apache.org/jira/browse/ZEPPELIN-6536

@voidmatcha voidmatcha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.

@miinhho

miinhho commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review and for splitting the suggested fixes into separate commits. 😄 🙇‍♂️

I applied the changes for the Playwright base URL override, the explicit classic e2e script, the classic test conventions docs, and the auth-matrix classic skip.

@voidmatcha voidmatcha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since collaborativeMode.spec.js was fully commented out and deleted rather than ported, could we leave a visible follow-up near the migrated classic specs?

For example, a skipped placeholder in zeppelin-web-angular/e2e/tests/classic/classic-collaborative-mode.spec.ts with a named TODO to port the old disabled collaborative editing scenario later.

The deleted file already pointed to https://issues.apache.org/jira/browse/ZEPPELIN-5674, so we could reference that there as well.

voidmatcha@12b4edb

Not a blocker, but it would make the migration more traceable.

Comment on lines +21 to +22
const countSubstringOccurrence = (text: string, substring: string): number =>
(text.match(new RegExp(substring, 'g')) || []).length;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

countSubstringOccurrence() uses new RegExp(substring, 'g'). Current terms are plain (t, te), but literal counting would be safer for future regex metacharacter cases.

Suggested change
const countSubstringOccurrence = (text: string, substring: string): number =>
(text.match(new RegExp(substring, 'g')) || []).length;
const countSubstringOccurrence = (text: string, substring: string): number =>
substring ? text.split(substring).length - 1 : 0;

@voidmatcha

Copy link
Copy Markdown
Member

Could you rebase this onto master?

@miinhho

miinhho commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

I resolved the conflict via GitHub, which updated the branch with master and made it mergeable. I realized afterward that this produced a merge commit rather than a rebase.

Happy to redo it as a local rebase and force-push if you prefer the linear history.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants