build: resolve CI failures

Resolves some e2e failures that only happened on CI.

(cherry picked from commit 262fba7f7d)
This commit is contained in:
Kristiyan Kostadinov
2026-08-14 10:11:35 +02:00
committed by Jessica Janiuk
parent e120d2830b
commit 0cd243d99a
11 changed files with 74 additions and 42 deletions
+3 -6
View File
@@ -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],
)
@@ -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",
],
@@ -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.
@@ -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<webdriver.logging.Entry[]> {
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,
@@ -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
@@ -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);
@@ -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);
@@ -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();
});
@@ -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);
@@ -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();
});
});
@@ -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 `<link rel="preconnect">` 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