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

chanholee 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 0a768bcc07 [ZEPPELIN-6370] Upgrade playwright and change the method of 
installing Playwright browsers
0a768bcc07 is described below

commit 0a768bcc07a4b691df51eda8f26cc013e8773612
Author: YONGJAE LEE(이용재) <[email protected]>
AuthorDate: Fri Oct 24 13:01:44 2025 +0900

    [ZEPPELIN-6370] Upgrade playwright and change the method of installing 
Playwright browsers
    
    ### What is this PR for?
    https://github.com/apache/zeppelin/pull/5107
    
https://github.com/apache/zeppelin/actions/runs/18662031473/job/53204596550?pr=5107
    
    In the Playwright E2E tests of the above bump PR, the following issue 
occurred:
    ```
    Error: browserType.launch: Executable doesn't exist at 
/home/runner/.cache/ms-playwright/webkit-2215/pw_run.sh
    ```
    
    This issue seems to be caused by the Playwright browser installation step 
being version-locked in `zeppelin-web-angular/pom.xml`'s playwright-install 
execution.
    
    Instead of managing it in `pom.xml`, it would be better to add it to the 
`postinstall` script in `zeppelin-web-angular/package.json`, so that Playwright 
browsers are automatically installed when running `npm install`, either in CI 
and on a local environment. This PR addresses that change.
    
    61ff629c48f5f0cc552fa8a9b87d3e665b8601ea
    
    Including the CI caching procedure as above, it seems optimized as previous 
approach(pom.xml).
    
    ### What type of PR is it?
    Improvement
    
    ### Todos
    
    ### What is the Jira issue?
    ZEPPELIN-6370
    
    ### 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 #5108 from dididy/e2e/upgrade-playwright.
    
    Signed-off-by: ChanHo Lee <[email protected]>
---
 .github/workflows/frontend.yml                     |  7 ++++
 .../e2e/tests/theme/dark-mode.spec.ts              | 31 ++++++++-------
 zeppelin-web-angular/package-lock.json             | 46 +++++++++++-----------
 zeppelin-web-angular/package.json                  |  4 +-
 zeppelin-web-angular/playwright.config.ts          |  4 ++
 zeppelin-web-angular/pom.xml                       | 16 --------
 6 files changed, 53 insertions(+), 55 deletions(-)

diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index 66e5c5baf5..8cdd0f808a 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -75,6 +75,13 @@ jobs:
         with:
           distribution: 'temurin'
           java-version: 11
+      - name: Cache Playwright browsers
+        uses: actions/cache@v4
+        with:
+          path: ~/.cache/ms-playwright
+          key: ${{ runner.os }}-playwright-${{ 
hashFiles('zeppelin-web-angular/package-lock.json') }}
+          restore-keys: |
+            ${{ runner.os }}-playwright-
       - name: Cache local Maven repository
         uses: actions/cache@v4
         with:
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 9b8423dacd..aac56d589c 100644
--- a/zeppelin-web-angular/e2e/tests/theme/dark-mode.spec.ts
+++ b/zeppelin-web-angular/e2e/tests/theme/dark-mode.spec.ts
@@ -20,7 +20,7 @@ test.describe('Dark Mode Theme Switching', () => {
 
   test.beforeEach(async ({ page }) => {
     themePage = new ThemePage(page);
-    await page.goto('/', { waitUntil: 'load' });
+    await page.goto('/');
     await waitForZeppelinReady(page);
 
     // Handle authentication if shiro.ini exists
@@ -30,7 +30,9 @@ test.describe('Dark Mode Theme Switching', () => {
     await themePage.clearLocalStorage();
   });
 
-  test('Scenario: User can switch to dark mode and persistence is maintained', 
async ({ page }) => {
+  test('Scenario: User can switch to dark mode and persistence is maintained', 
async ({ page, context }) => {
+    let currentPage = page;
+
     // GIVEN: User is on the main page, which starts in 'system' mode by 
default (localStorage cleared).
     await test.step('GIVEN the page starts in system mode', async () => {
       await themePage.assertSystemTheme(); // Robot icon for system theme
@@ -47,19 +49,20 @@ test.describe('Dark Mode Theme Switching', () => {
     // WHEN: User switches to dark mode by setting localStorage and reloading.
     await test.step('WHEN the user switches to dark mode', async () => {
       await themePage.setThemeInLocalStorage('dark');
-      await page.reload();
-      await waitForZeppelinReady(page);
-    });
+      const newPage = await context.newPage();
+      await newPage.goto(currentPage.url());
+      await waitForZeppelinReady(newPage);
 
-    // THEN: The theme changes to dark mode.
-    await test.step('THEN the page switches to dark mode', async () => {
+      // Update themePage to use newPage and verify dark mode
+      themePage = new ThemePage(newPage);
+      currentPage = newPage;
       await themePage.assertDarkTheme();
     });
 
     // AND: User refreshes the page.
     await test.step('AND the user refreshes the page', async () => {
-      await page.reload();
-      await waitForZeppelinReady(page);
+      await currentPage.reload();
+      await waitForZeppelinReady(currentPage);
     });
 
     // THEN: Dark mode is maintained after refresh.
@@ -84,7 +87,7 @@ test.describe('Dark Mode Theme Switching', () => {
 
     await test.step('GIVEN: No localStorage, System preference is Light', 
async () => {
       await page.emulateMedia({ colorScheme: 'light' });
-      await page.goto('/', { waitUntil: 'load' });
+      await page.goto('/');
       await waitForZeppelinReady(page);
       // When no explicit theme is set, it defaults to 'system' mode
       // Even in system mode with light preference, the icon should be robot
@@ -95,7 +98,7 @@ test.describe('Dark Mode Theme Switching', () => {
 
     await test.step('GIVEN: No localStorage, System preference is Dark 
(initial system state)', async () => {
       await themePage.setThemeInLocalStorage('system');
-      await page.goto('/', { waitUntil: 'load' });
+      await page.goto('/');
       await waitForZeppelinReady(page);
       await themePage.assertSystemTheme(); // Robot icon for system theme
     });
@@ -103,7 +106,7 @@ test.describe('Dark Mode Theme Switching', () => {
     await test.step("GIVEN: localStorage is 'dark', System preference is 
Light", async () => {
       await themePage.setThemeInLocalStorage('dark');
       await page.emulateMedia({ colorScheme: 'light' });
-      await page.goto('/', { waitUntil: 'load' });
+      await page.goto('/');
       await waitForZeppelinReady(page);
       await themePage.assertDarkTheme(); // localStorage should override system
     });
@@ -111,7 +114,7 @@ test.describe('Dark Mode Theme Switching', () => {
     await test.step("GIVEN: localStorage is 'system', THEN: Emulate system 
preference change to Light", async () => {
       await themePage.setThemeInLocalStorage('system');
       await page.emulateMedia({ colorScheme: 'light' });
-      await page.goto('/', { waitUntil: 'load' });
+      await page.goto('/');
       await waitForZeppelinReady(page);
       await expect(themePage.rootElement).toHaveClass(/light/);
       await expect(themePage.rootElement).toHaveAttribute('data-theme', 
'light');
@@ -121,7 +124,7 @@ test.describe('Dark Mode Theme Switching', () => {
     await test.step("GIVEN: localStorage is 'system', THEN: Emulate system 
preference change to Dark", async () => {
       await themePage.setThemeInLocalStorage('system');
       await page.emulateMedia({ colorScheme: 'dark' });
-      await page.goto('/', { waitUntil: 'load' });
+      await page.goto('/');
       await waitForZeppelinReady(page);
       await expect(themePage.rootElement).toHaveClass(/dark/);
       await expect(themePage.rootElement).toHaveAttribute('data-theme', 
'dark');
diff --git a/zeppelin-web-angular/package-lock.json 
b/zeppelin-web-angular/package-lock.json
index e0aef784f7..6ae0b6a5a0 100644
--- a/zeppelin-web-angular/package-lock.json
+++ b/zeppelin-web-angular/package-lock.json
@@ -48,7 +48,7 @@
         "@angular/cli": "~9.1.15",
         "@angular/compiler-cli": "~9.1.13",
         "@angular/language-service": "~9.1.13",
-        "@playwright/test": "1.53.2",
+        "@playwright/test": "1.56.1",
         "@types/angular": "^1.8.0",
         "@types/diff-match-patch": "^1.0.36",
         "@types/highlight.js": "^9.12.3",
@@ -2168,13 +2168,13 @@
       }
     },
     "node_modules/@playwright/test": {
-      "version": "1.53.2",
-      "resolved": 
"https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz";,
-      "integrity": 
"sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==",
+      "version": "1.56.1",
+      "resolved": 
"https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz";,
+      "integrity": 
"sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==",
       "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
-        "playwright": "1.53.2"
+        "playwright": "1.56.1"
       },
       "bin": {
         "playwright": "cli.js"
@@ -12408,13 +12408,13 @@
       }
     },
     "node_modules/playwright": {
-      "version": "1.53.2",
-      "resolved": 
"https://registry.npmjs.org/playwright/-/playwright-1.53.2.tgz";,
-      "integrity": 
"sha512-6K/qQxVFuVQhRQhFsVZ9fGeatxirtrpPgxzBYWyZLEXJzqYwuL4fuNmfOfD5et1tJE4GScKyPNeLhZeRwuTU3A==",
+      "version": "1.56.1",
+      "resolved": 
"https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz";,
+      "integrity": 
"sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==",
       "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
-        "playwright-core": "1.53.2"
+        "playwright-core": "1.56.1"
       },
       "bin": {
         "playwright": "cli.js"
@@ -12427,9 +12427,9 @@
       }
     },
     "node_modules/playwright-core": {
-      "version": "1.53.2",
-      "resolved": 
"https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.2.tgz";,
-      "integrity": 
"sha512-ox/OytMy+2w1jcYEYlOo1Hhp8hZkLCximMTUTMBXjGUA1KoFfiSZ+DU+3a739jsPY0yoKH2TFy9S2fsJas8yAw==",
+      "version": "1.56.1",
+      "resolved": 
"https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz";,
+      "integrity": 
"sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==",
       "dev": true,
       "license": "Apache-2.0",
       "bin": {
@@ -20845,12 +20845,12 @@
       }
     },
     "@playwright/test": {
-      "version": "1.53.2",
-      "resolved": 
"https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz";,
-      "integrity": 
"sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==",
+      "version": "1.56.1",
+      "resolved": 
"https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz";,
+      "integrity": 
"sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==",
       "dev": true,
       "requires": {
-        "playwright": "1.53.2"
+        "playwright": "1.56.1"
       }
     },
     "@rollup/plugin-commonjs": {
@@ -27746,13 +27746,13 @@
       }
     },
     "playwright": {
-      "version": "1.53.2",
-      "resolved": 
"https://registry.npmjs.org/playwright/-/playwright-1.53.2.tgz";,
-      "integrity": 
"sha512-6K/qQxVFuVQhRQhFsVZ9fGeatxirtrpPgxzBYWyZLEXJzqYwuL4fuNmfOfD5et1tJE4GScKyPNeLhZeRwuTU3A==",
+      "version": "1.56.1",
+      "resolved": 
"https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz";,
+      "integrity": 
"sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==",
       "dev": true,
       "requires": {
         "fsevents": "2.3.2",
-        "playwright-core": "1.53.2"
+        "playwright-core": "1.56.1"
       },
       "dependencies": {
         "fsevents": {
@@ -27765,9 +27765,9 @@
       }
     },
     "playwright-core": {
-      "version": "1.53.2",
-      "resolved": 
"https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.2.tgz";,
-      "integrity": 
"sha512-ox/OytMy+2w1jcYEYlOo1Hhp8hZkLCximMTUTMBXjGUA1KoFfiSZ+DU+3a739jsPY0yoKH2TFy9S2fsJas8yAw==",
+      "version": "1.56.1",
+      "resolved": 
"https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz";,
+      "integrity": 
"sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==",
       "dev": true
     },
     "please-upgrade-node": {
diff --git a/zeppelin-web-angular/package.json 
b/zeppelin-web-angular/package.json
index eef8b768ee..1f5db66436 100644
--- a/zeppelin-web-angular/package.json
+++ b/zeppelin-web-angular/package.json
@@ -3,7 +3,7 @@
   "version": "0.0.0",
   "scripts": {
     "prepare": "cd .. && husky",
-    "postinstall": "npm run build:projects && npm run build:tslint-rules",
+    "postinstall": "npm run build:projects && npm run build:tslint-rules && 
npx playwright install --with-deps",
     "ng": "./node_modules/.bin/ng",
     "start": "cross-env NODE_OPTIONS=--openssl-legacy-provider ng serve 
--proxy-config proxy.conf.js --extra-webpack-config webpack.partial.js",
     "build": "cross-env NODE_OPTIONS=--openssl-legacy-provider ng build --prod 
--extra-webpack-config webpack.partial.js",
@@ -68,7 +68,7 @@
     "@angular/cli": "~9.1.15",
     "@angular/compiler-cli": "~9.1.13",
     "@angular/language-service": "~9.1.13",
-    "@playwright/test": "1.53.2",
+    "@playwright/test": "1.56.1",
     "@types/angular": "^1.8.0",
     "@types/diff-match-patch": "^1.0.36",
     "@types/highlight.js": "^9.12.3",
diff --git a/zeppelin-web-angular/playwright.config.ts 
b/zeppelin-web-angular/playwright.config.ts
index 0dd3e2d6dc..8d845d5832 100644
--- a/zeppelin-web-angular/playwright.config.ts
+++ b/zeppelin-web-angular/playwright.config.ts
@@ -21,6 +21,10 @@ export default defineConfig({
   forbidOnly: !!process.env.CI,
   retries: process.env.CI ? 2 : 0,
   workers: 4,
+  timeout: 120000,
+  expect: {
+    timeout: 60000
+  },
   reporter: [
     [!!process.env.CI ? 'github' : 'list'],
     ['html', { open: !!process.env.CI ? 'never' : 'always' }],
diff --git a/zeppelin-web-angular/pom.xml b/zeppelin-web-angular/pom.xml
index 68c1181e21..b488fefaae 100644
--- a/zeppelin-web-angular/pom.xml
+++ b/zeppelin-web-angular/pom.xml
@@ -161,22 +161,6 @@
             </goals>
           </execution>
 
-          <execution>
-            <id>playwright-install</id>
-            <phase>pre-integration-test</phase>
-            <configuration>
-              <skip>${web.e2e.disabled}</skip>
-              <target unless="skipTests">
-                <exec executable="./node/npx" spawn="false">
-                  <arg line="[email protected] install --with-deps" />
-                </exec>
-              </target>
-            </configuration>
-            <goals>
-              <goal>run</goal>
-            </goals>
-          </execution>
-
           <execution>
             <id>stop-zeppelin</id>
             <phase>post-integration-test</phase>

Reply via email to