Protractor ignoreSynchronization configuration for mixed Angular and non‑Angular pages
0 reputation · 10 Jun 2022, 13:03 UTC
0 reputation · 10 Jun 2022, 13:03 UTC
Goal: ensure Protractor executes actions reliably on pages that switch between Angular‑rendered views and server‑side or static content without timing out or performing steps too early.
Constraint: the ignoreSynchronization flag defaults to false, which tells Protractor to wait for Angular bootstraps; however, there is no documented rule for when to set it to true in mixed‑mode applications, and the appropriate value may differ between local developer machines and production CI pipelines where extra bundles or lazy modules affect timing.
Specific questions: Should ignoreSynchronization be configured globally or overridden per‑test step? How can a team determine the correct value for a given mix of Angular and non‑Angular navigation? What lightweight verification can confirm that the flag prevents hangs without altering test logic?
34775 reputation · 10 Jun 2022, 18:04 UTC
Do not set ignoreSynchronization globally. Leave Angular synchronization on by default, and toggle it off only around the specific steps that touch non-Angular pages, then turn it back on immediately. The flag is session-wide, not per-page, so a global true silently removes all of Protractor's built-in waiting and makes your Angular tests flaky.
With synchronization enabled (the default), Protractor waits for Angular's $http and $timeout queues to drain before each command. On a server-rendered or static page there is no Angular to signal, so the wait either fails or times out. That is the only situation the flag exists for.
Use the modern API browser.waitForAngularEnabled(). The older browser.ignoreSynchronization = true still works in many versions but is deprecated in later releases — check which your installed version supports.
async function visitStaticPage(url) {
await browser.waitForAngularEnabled(false);
await browser.driver.get(url); // use driver.get, not browser.get
// sync is off: add explicit waits, Protractor no longer waits for you
const el = element(by.css('#content'));
await browser.wait(ExpectedConditions.visibilityOf(el), 5000);
// ... assertions ...
await browser.waitForAngularEnabled(true); // re-enable before Angular navigation
}Two details matter here:
ExpectedConditions wait (or equivalent), otherwise you trade hangs for race conditions.waitForAngularEnabled(true) is the most common cause of "works locally, flakes in CI" — the next Angular test runs with no synchronization and passes or fails unpredictably depending on machine speed. Wrap the toggle in a helper (or try/finally) so it cannot be skipped.The correct value is determined by the page, not the environment. If local and CI behave differently, the cause is usually timing (lazy bundles loading slower in CI), not a need for a different flag value. Fix that with longer explicit-wait timeouts in CI config, not by changing synchronization. The exception: if an Angular page never stabilizes because of polling ($interval, long-polling), synchronization will hang no matter what — the real fix is moving that work outside Angular's zone, not disabling sync globally.
await browser.waitForAngularEnabled() at each step to confirm the flag actually toggles where you think it does.Note: Protractor is end-of-life, so treat this as maintenance knowledge; new suites should target Playwright, WebdriverIO, or Cypress, which handle Angular waiting differently.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 10 Jun 2022, 14:08 UTC
When you call browser.waitForAngularEnabled(false), Protractor stops its automatic wait for Angular’s $http and $timeout queues, but it still honors any explicit or implicit waits you have set (e.g., browser.manage().timeouts().implicitlyWait() or ExpectedConditions). Therefore, after navigating to a non‑Angular page you must still wait for the DOM to be ready using an explicit wait such as browser.wait(ExpectedConditions.presenceOfElementLocated(By.css('#content')), 5000). Before returning to an Angular view, re‑enable synchronization with browser.waitForAngularEnabled(true) and then call browser.waitForAngular() (or rely on the next command’s built‑in wait) to let Protractor re‑synchronize with the newly bootstrapped Angular app. This pattern works in Protractor 5.4+ where waitForAngularEnabled replaces the deprecated ignoreSynchronization flag.