From 0cd243d99ab2b73c88d70d595dbf003c8ab8334c Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 14 Aug 2026 10:11:35 +0200 Subject: [PATCH] build: resolve CI failures Resolves some e2e failures that only happened on CI. (cherry picked from commit 262fba7f7d1ec4ec5aba5295cda8fdb0474d65a9) --- modules/playground/e2e_test/example_test.bzl | 9 +++----- .../playground/e2e_test/sourcemap/BUILD.bazel | 1 - .../e2e/basic/basic.e2e-spec.ts | 6 +++-- .../image-directive/e2e/browser-logs-util.ts | 22 +++++++++++++++++++ .../e2e/fill-mode/fill-mode.e2e-spec.ts | 7 ++++-- .../image-distortion.e2e-spec.ts | 19 ++++++++-------- .../image-perf-warnings-lazy.e2e-spec.ts | 8 ++----- .../image-perf-warnings-oversized.e2e-spec.ts | 11 +++++----- .../e2e/lcp-check/lcp-check.e2e-spec.ts | 13 +++++++---- .../oversized-image.e2e-spec.ts | 14 ++++++++---- .../preconnect-check.e2e-spec.ts | 6 +++-- 11 files changed, 74 insertions(+), 42 deletions(-) diff --git a/modules/playground/e2e_test/example_test.bzl b/modules/playground/e2e_test/example_test.bzl index 3f24b10e2e9..2e7311a29a2 100644 --- a/modules/playground/e2e_test/example_test.bzl +++ b/modules/playground/e2e_test/example_test.bzl @@ -7,13 +7,12 @@ def example_test( data = [], deps = [], external = [], - tsconfig = "//modules/playground:tsconfig_e2e", - use_legacy_webdriver_types = False): + tsconfig = "//modules/playground:tsconfig_e2e"): ts_project( name = "%s_lib" % name, testonly = True, srcs = srcs, - tsconfig = "//modules/playground:tsconfig_e2e", + tsconfig = tsconfig, deps = deps + [ "//modules:node_modules/@types/jasmine", "//modules:node_modules/@types/selenium-webdriver", @@ -27,7 +26,5 @@ def example_test( server = server, data = data, external = external, - deps = [ - ":%s_lib" % name, - ], + deps = [":%s_lib" % name], ) diff --git a/modules/playground/e2e_test/sourcemap/BUILD.bazel b/modules/playground/e2e_test/sourcemap/BUILD.bazel index 9fbd8ddb771..4ec0cda3c35 100644 --- a/modules/playground/e2e_test/sourcemap/BUILD.bazel +++ b/modules/playground/e2e_test/sourcemap/BUILD.bazel @@ -10,7 +10,6 @@ example_test( # Source-Map is using WASM and cannot be bundled for specs. external = ["source-map"], server = "//modules/playground/src/sourcemap:devserver", - use_legacy_webdriver_types = False, deps = [ "//modules:node_modules/source-map", ], diff --git a/packages/core/test/bundling/image-directive/e2e/basic/basic.e2e-spec.ts b/packages/core/test/bundling/image-directive/e2e/basic/basic.e2e-spec.ts index e53ea4c50da..9a3909ec879 100644 --- a/packages/core/test/bundling/image-directive/e2e/basic/basic.e2e-spec.ts +++ b/packages/core/test/bundling/image-directive/e2e/basic/basic.e2e-spec.ts @@ -7,7 +7,7 @@ */ import * as webdriver from 'selenium-webdriver'; -import {collectBrowserLogs, createWebDriver} from '../browser-logs-util'; +import {createWebDriver, waitForBrowserLogs} from '../browser-logs-util'; describe('NgOptimizedImage directive (basic)', () => { let driver: webdriver.WebDriver; @@ -29,7 +29,9 @@ describe('NgOptimizedImage directive (basic)', () => { // Since there are no preconnect tags on a page, // we expect a log in a console that mentions that. - const logs = await collectBrowserLogs(driver, webdriver.logging.Level.WARNING); + const logs = await waitForBrowserLogs(driver, webdriver.logging.Level.WARNING, 1, 10000, (l) => + l.message.includes('NG02956'), + ); expect(logs.length).toEqual(1); // Verify that the error code and a raw image src are present. diff --git a/packages/core/test/bundling/image-directive/e2e/browser-logs-util.ts b/packages/core/test/bundling/image-directive/e2e/browser-logs-util.ts index 7f3f149e3eb..53ae1af75ad 100644 --- a/packages/core/test/bundling/image-directive/e2e/browser-logs-util.ts +++ b/packages/core/test/bundling/image-directive/e2e/browser-logs-util.ts @@ -92,6 +92,28 @@ export async function collectBrowserLogs( return collectedLogs; } +export async function waitForBrowserLogs( + driver: webdriver.WebDriver, + loggingLevel: webdriver.logging.Level, + minCount: number, + timeoutMs: number = 10000, + filterFn?: (entry: webdriver.logging.Entry) => boolean, + collectMoreSevereErrors: boolean = false, +): Promise { + const collectedLogs: webdriver.logging.Entry[] = []; + const startTime = Date.now(); + while (Date.now() - startTime < timeoutMs) { + const newLogs = await collectBrowserLogs(driver, loggingLevel, collectMoreSevereErrors); + const filtered = filterFn ? newLogs.filter(filterFn) : newLogs; + collectedLogs.push(...filtered); + if (collectedLogs.length >= minCount) { + return collectedLogs; + } + await new Promise((resolve) => setTimeout(resolve, 150)); + } + return collectedLogs; +} + export async function verifyNoBrowserErrors(driver: webdriver.WebDriver) { const logs = await collectBrowserLogs( driver, diff --git a/packages/core/test/bundling/image-directive/e2e/fill-mode/fill-mode.e2e-spec.ts b/packages/core/test/bundling/image-directive/e2e/fill-mode/fill-mode.e2e-spec.ts index 15c49e1bd08..366d8ac477a 100644 --- a/packages/core/test/bundling/image-directive/e2e/fill-mode/fill-mode.e2e-spec.ts +++ b/packages/core/test/bundling/image-directive/e2e/fill-mode/fill-mode.e2e-spec.ts @@ -7,7 +7,7 @@ */ import * as webdriver from 'selenium-webdriver'; -import {collectBrowserLogs, createWebDriver} from '../browser-logs-util'; +import {collectBrowserLogs, createWebDriver, waitForBrowserLogs} from '../browser-logs-util'; describe('NgOptimizedImage directive (fill-mode)', () => { let driver: webdriver.WebDriver; @@ -23,13 +23,16 @@ describe('NgOptimizedImage directive (fill-mode)', () => { it('should not warn when an image in the fill mode is rendered correctly', async () => { await driver.get(`${baseUrl}/e2e/fill-mode-passing`); + await new Promise((resolve) => setTimeout(resolve, 600)); const logs = await collectBrowserLogs(driver, webdriver.logging.Level.WARNING); expect(logs.length).toEqual(0); }); it('should warn if an image in the fill mode has zero height after rendering', async () => { await driver.get(`${baseUrl}/e2e/fill-mode-failing`); - const logs = await collectBrowserLogs(driver, webdriver.logging.Level.WARNING); + const logs = await waitForBrowserLogs(driver, webdriver.logging.Level.WARNING, 1, 10000, (l) => + l.message.includes('NG02952'), + ); expect(logs.length).toEqual(1); // Image loading order is not guaranteed, so all logs, rather than single entry diff --git a/packages/core/test/bundling/image-directive/e2e/image-distortion/image-distortion.e2e-spec.ts b/packages/core/test/bundling/image-directive/e2e/image-distortion/image-distortion.e2e-spec.ts index b36aafb876a..921099efc95 100644 --- a/packages/core/test/bundling/image-directive/e2e/image-distortion/image-distortion.e2e-spec.ts +++ b/packages/core/test/bundling/image-directive/e2e/image-distortion/image-distortion.e2e-spec.ts @@ -7,7 +7,7 @@ */ import * as webdriver from 'selenium-webdriver'; -import {collectBrowserLogs, createWebDriver} from '../browser-logs-util'; +import {collectBrowserLogs, createWebDriver, waitForBrowserLogs} from '../browser-logs-util'; describe('NgOptimizedImage directive (image-distortion)', () => { let driver: webdriver.WebDriver; @@ -15,6 +15,12 @@ describe('NgOptimizedImage directive (image-distortion)', () => { beforeAll(async () => { ({driver, baseUrl} = await createWebDriver()); + + // Prime the memory cache with `a.png` by visiting the passing component first. + // Chromium's native lazy loading defers `display: none` images indefinitely + // unless they are already in the memory cache. + await driver.get(`${baseUrl}/e2e/image-distortion-passing`); + await new Promise((r) => setTimeout(r, 1000)); }); afterAll(async () => { @@ -30,14 +36,9 @@ describe('NgOptimizedImage directive (image-distortion)', () => { it('should warn if there is image distortion', async () => { await driver.get(`${baseUrl}/e2e/image-distortion-failing`); - const logs: webdriver.logging.Entry[] = []; - const startTime = Date.now(); - while (Date.now() - startTime < 5000) { - const newLogs = await collectBrowserLogs(driver, webdriver.logging.Level.WARNING); - logs.push(...newLogs); - if (logs.length >= 8) break; - await new Promise((r) => setTimeout(r, 200)); - } + const logs = await waitForBrowserLogs(driver, webdriver.logging.Level.WARNING, 8, 15000, (l) => + l.message.includes('NG02952'), + ); expect(logs.length).toEqual(8); diff --git a/packages/core/test/bundling/image-directive/e2e/image-perf-warnings-lazy/image-perf-warnings-lazy.e2e-spec.ts b/packages/core/test/bundling/image-directive/e2e/image-perf-warnings-lazy/image-perf-warnings-lazy.e2e-spec.ts index acdf47afc8f..d88d4449414 100644 --- a/packages/core/test/bundling/image-directive/e2e/image-perf-warnings-lazy/image-perf-warnings-lazy.e2e-spec.ts +++ b/packages/core/test/bundling/image-directive/e2e/image-perf-warnings-lazy/image-perf-warnings-lazy.e2e-spec.ts @@ -7,7 +7,7 @@ */ import * as webdriver from 'selenium-webdriver'; -import {collectBrowserLogs, createWebDriver} from '../browser-logs-util'; +import {createWebDriver, waitForBrowserLogs} from '../browser-logs-util'; describe('Image performance warnings (lazy)', () => { let driver: webdriver.WebDriver; @@ -23,8 +23,6 @@ describe('Image performance warnings (lazy)', () => { it('should log a warning when a LCP image is loaded lazily', async () => { await driver.get(`${baseUrl}/e2e/image-perf-warnings-lazy`); - // Wait for load event - await new Promise((resolve) => setTimeout(resolve, 600)); // Verify that both images were rendered. const imgs = await driver.findElements(webdriver.By.css('img')); let srcA = await imgs[0].getAttribute('src'); @@ -34,9 +32,7 @@ describe('Image performance warnings (lazy)', () => { // Make sure that only one LCP performance warning is in the console for image `a.png`, // since `b.png` should be below the fold and not treated as an LCP element. - // NOTE: We specifically filter on the IMAGE_PERFORMANCE_WARNING (913) code because the browser - // or framework may emit other unrelated warning logs here. - const logs = (await collectBrowserLogs(driver, webdriver.logging.Level.WARNING)).filter((l) => + const logs = await waitForBrowserLogs(driver, webdriver.logging.Level.WARNING, 1, 10000, (l) => l.message.includes('NG0913'), ); expect(logs.length).toEqual(1); diff --git a/packages/core/test/bundling/image-directive/e2e/image-perf-warnings-oversized/image-perf-warnings-oversized.e2e-spec.ts b/packages/core/test/bundling/image-directive/e2e/image-perf-warnings-oversized/image-perf-warnings-oversized.e2e-spec.ts index 2588f20c106..c4e1c6a5760 100644 --- a/packages/core/test/bundling/image-directive/e2e/image-perf-warnings-oversized/image-perf-warnings-oversized.e2e-spec.ts +++ b/packages/core/test/bundling/image-directive/e2e/image-perf-warnings-oversized/image-perf-warnings-oversized.e2e-spec.ts @@ -7,7 +7,7 @@ */ import * as webdriver from 'selenium-webdriver'; -import {collectBrowserLogs, createWebDriver} from '../browser-logs-util'; +import {collectBrowserLogs, createWebDriver, waitForBrowserLogs} from '../browser-logs-util'; describe('Image performance warnings (oversized)', () => { let driver: webdriver.WebDriver; @@ -23,13 +23,12 @@ describe('Image performance warnings (oversized)', () => { it('should warn if rendered image size is much smaller than intrinsic size', async () => { await driver.get(`${baseUrl}/e2e/image-perf-warnings-oversized`); - // Wait for load event - await new Promise((resolve) => setTimeout(resolve, 600)); - const logs = await collectBrowserLogs(driver, webdriver.logging.Level.WARNING); + const expectedMessageRegex = /has intrinsic file dimensions much larger than/; + const logs = await waitForBrowserLogs(driver, webdriver.logging.Level.WARNING, 1, 10000, (l) => + expectedMessageRegex.test(l.message), + ); expect(logs.length).toEqual(1); - - const expectedMessageRegex = /has intrinsic file dimensions much larger than/; expect(expectedMessageRegex.test(logs[0].message)).toBeTruthy(); }); diff --git a/packages/core/test/bundling/image-directive/e2e/lcp-check/lcp-check.e2e-spec.ts b/packages/core/test/bundling/image-directive/e2e/lcp-check/lcp-check.e2e-spec.ts index 3826f31cfbc..1045c7e06aa 100644 --- a/packages/core/test/bundling/image-directive/e2e/lcp-check/lcp-check.e2e-spec.ts +++ b/packages/core/test/bundling/image-directive/e2e/lcp-check/lcp-check.e2e-spec.ts @@ -7,7 +7,7 @@ */ import * as webdriver from 'selenium-webdriver'; -import {collectBrowserLogs, createWebDriver} from '../browser-logs-util'; +import {createWebDriver, waitForBrowserLogs} from '../browser-logs-util'; describe('NgOptimizedImage directive (lcp-check)', () => { let driver: webdriver.WebDriver; @@ -23,8 +23,9 @@ describe('NgOptimizedImage directive (lcp-check)', () => { it('should log a warning when a `priority` is missing on an LCP image', async () => { await driver.get(`${baseUrl}/e2e/lcp-check`); - // Wait for ngSrc to be modified - await new Promise((resolve) => setTimeout(resolve, 600)); + // Wait for ngSrc to be modified after 500ms timeout + await new Promise((resolve) => setTimeout(resolve, 800)); + // Verify that both images were rendered. const imgs = await driver.findElements(webdriver.By.css('img')); let srcB = await imgs[0].getAttribute('src'); @@ -40,7 +41,11 @@ describe('NgOptimizedImage directive (lcp-check)', () => { // We use >= 1 and check the last log because the browser may sometimes report `b.png` // as an intermediate LCP element before `a.png` is painted, causing an extra log. // NOTE: This highlights a potential bug where the directive warns on intermediate LCP elements. - const logs = (await collectBrowserLogs(driver, webdriver.logging.Level.SEVERE)).filter( + const logs = await waitForBrowserLogs( + driver, + webdriver.logging.Level.SEVERE, + 1, + 10000, (l) => l.message.includes(`NG02955`), // LCP_IMG_MISSING_PRIORITY ); expect(logs.length).toBeGreaterThanOrEqual(1); diff --git a/packages/core/test/bundling/image-directive/e2e/oversized-image/oversized-image.e2e-spec.ts b/packages/core/test/bundling/image-directive/e2e/oversized-image/oversized-image.e2e-spec.ts index 37aa0de8bee..e5562a7b308 100644 --- a/packages/core/test/bundling/image-directive/e2e/oversized-image/oversized-image.e2e-spec.ts +++ b/packages/core/test/bundling/image-directive/e2e/oversized-image/oversized-image.e2e-spec.ts @@ -7,7 +7,7 @@ */ import * as webdriver from 'selenium-webdriver'; -import {collectBrowserLogs, createWebDriver} from '../browser-logs-util'; +import {collectBrowserLogs, createWebDriver, waitForBrowserLogs} from '../browser-logs-util'; describe('NgOptimizedImage directive (oversized-image)', () => { let driver: webdriver.WebDriver; @@ -23,17 +23,23 @@ describe('NgOptimizedImage directive (oversized-image)', () => { it('should not warn if there is no oversized image', async () => { await driver.get(`${baseUrl}/e2e/oversized-image-passing`); + await new Promise((resolve) => setTimeout(resolve, 600)); const logs = await collectBrowserLogs(driver, webdriver.logging.Level.WARNING); expect(logs.length).toEqual(0); }); it('should warn if rendered image size is much smaller than intrinsic size', async () => { await driver.get(`${baseUrl}/e2e/oversized-image-failing`); - const logs = await collectBrowserLogs(driver, webdriver.logging.Level.WARNING); + const expectedMessageRegex = /the intrinsic image is significantly larger than necessary\./; + const logs = await waitForBrowserLogs( + driver, + webdriver.logging.Level.WARNING, + 1, + 10000, + (l) => expectedMessageRegex.test(l.message) || l.message.includes('NG02960'), + ); expect(logs.length).toEqual(1); - - const expectedMessageRegex = /the intrinsic image is significantly larger than necessary\./; expect(expectedMessageRegex.test(logs[0].message)).toBeTruthy(); }); }); diff --git a/packages/core/test/bundling/image-directive/e2e/preconnect-check/preconnect-check.e2e-spec.ts b/packages/core/test/bundling/image-directive/e2e/preconnect-check/preconnect-check.e2e-spec.ts index 7b508ed49a9..65b10d90b60 100644 --- a/packages/core/test/bundling/image-directive/e2e/preconnect-check/preconnect-check.e2e-spec.ts +++ b/packages/core/test/bundling/image-directive/e2e/preconnect-check/preconnect-check.e2e-spec.ts @@ -7,7 +7,7 @@ */ import * as webdriver from 'selenium-webdriver'; -import {collectBrowserLogs, createWebDriver} from '../browser-logs-util'; +import {collectBrowserLogs, createWebDriver, waitForBrowserLogs} from '../browser-logs-util'; // Verifies that both images used in a component were rendered. async function verifyImagesPresent(driver: webdriver.WebDriver) { @@ -38,7 +38,9 @@ describe('NgOptimizedImage directive (preconnect-check)', () => { // Make sure that only one warning is in the console for both images, // because they both have the same base URL (which is used to look for // corresponding `` tags). - const logs = await collectBrowserLogs(driver, webdriver.logging.Level.WARNING); + const logs = await waitForBrowserLogs(driver, webdriver.logging.Level.WARNING, 1, 10000, (l) => + l.message.includes('NG02956'), + ); expect(logs.length).toEqual(1); // Verify that the error code and a raw image src are present in the