重定向到 Auth0 非 Angular 页面后量角器同步到 Angular 页面

Protractor syncing to an Angular page after redirection to Auth0 non-Angular page

我有一个 Angular 网络应用程序,它使用 Protractor 进行端到端测试。我最近添加了 OAuth0 身份验证。在使用 await browser.waitForAngularEnabled(false) 重定向到非 Angular OAuth0 页面之前,我禁用了 Angular 同步并且工作正常。但是,我无法为该规范文件测试套件的其余部分再次使用 await browser.waitForAngularEnabled(true) 重新启用 Angular 同步,否则我会收到臭名昭著的量角器超时错误。我想重新启用 Angular 同步,否则我必须使用预期条件、等待和睡眠以确保加载后续页面,这可能会导致间歇性错误。

我已经阅读了所有问题和答案并尝试了所有显而易见的方法 - 重新加载页面、获取新页面、等待、长时间睡眠等。

所以我的问题很具体,而不是寻求建议 - 有没有人了解量角器用于与 Angular 页面同步的机制,你知道 Angular 是否有可能重新同步在重定向到非 Angular 页面并从非 Angular 页面返回后,即我是在浪费时间寻找修复程序。我阅读了一些关于该机制的内容 - 它在页面上加载了一个脚本 运行 但我不确定为什么当我执行 browser.get{'/')从 auth0 重定向返回后。

请注意,我可以让 Angular 同步处于禁用状态并且可以让事情正常进行,所以我并不是在征求有关如何让事情正常工作的建议。如果您遇到了特定问题并提出了解决方案,我很乐意听到。

感谢任何帮助。

回答 - 是的,您可以在量角器中重新启用 angular。但是,量角器并不总是适用于 angular 个应用程序。因此,只需确保量角器同步能够与您的应用程序正常工作,并且页面已为此做好准备。

首先,手动打开应用程序,并获得授权。然后在控制台 运行 getAllAngularTestabilities()。如果此命令不可用,protractor 将无法与 angular 一起使用。如果命令成功,请查看返回的对象,特别是 obj[0]._ngZonehasPendingMacrotaskshasPendingMicrotasks 属性。如果它们中的任何一个是 trueprotractor 不能在这个页面上工作。如果两者都是false则可以进行下一步

现在,当你现在页面可以与量角器对话时 browser.waitForAngularEnabled(true) 你需要为你的测试实现以下方法

let login = async function (username, password) {
  await browser.waitForAngularEnabled(false);
  await browser.get(url);
  await $usernameInput.sendKeys(username);
  await $passwordInput.sendKeys(password);
  await $loginButton.click();
  // MOST IMPORTANTLY, YOU HAVE TO WAIT UNTIL YOUR APP FULLY LOADED
  await browser.wait(
    // whatever you need to wait for,
    timeout,
    'failure message'
  );
  // AND FINALLY
  await browser.waitForAngularEnabled(true);
}

我的意思是你不一定非要有这个方法,我只是向你展示了实现结果所必须遵循的操作顺序。

基本上,重点是,当您登录时,确保非angular登录页面消失,并且您的angular页面在重新启用等待angular之前已完全加载.

您可以使用两种方法:

  • 等待所有关键元素出现
  • 或者写一个函数返回 return !obj[0]._ngZone.hasPendingMacrotasks && !obj[0]._ngZone.hasPendingMicrotasks 并将它传递给 browser.wait

我的回答供大家参考:

看来,当 auth0-spa-js SDK 的 createAuth0Client 方法(用于在 Angular SPA 应用程序上实施 Auth0 身份验证)在 Auth0 站点重定向后被调用时(成功身份验证后) ) hasPendingMacroTasks 设置为 true 并且永远不会重置。如上所述,这会阻止 Protractor 同步。

我重构了 auth0-spa-js 的实现以匹配 Auth0 网站上的最新指南(使用 Observables 而不是 async-await)并且存在完全相同的问题。

我调查了 createAuth0Client 在做什么:它在重定向到应用程序之前从 Auth0 服务器获得了一个 JWT(令牌),当它被调用时,它缓存该令牌并设置一个计时器来删除该缓存条目。 createAuth0Client 中的 setTimeout 调用由 Angular Zone 包装,并保持 hasPendingMacroTasks 为真,这会阻止 Protractor 收到 Angular 已完成加载的通知。计时器设置为令牌的生命周期,这是在 Auth0 服务器中设置的一个设置,因此我通过将令牌超时设置为 3 秒来测试它,并且 hasPendingMacroTasks 被重置为 false 并且量角器在我的 e2e 中等待 5 秒后成功同步测试。但是,一旦计时器到期,量角器就必须再次登录 Auth0 服务器才能进行 API 调用,因此缩短计时器不是可行的解决方法。

我调查了 运行ning createAuth0Client 在 Angular NgZone 之外,但事实证明这即使不是不可能也是极其困难的:

  1. 您需要访问创建的 Auth0 客户端实例,一旦您在 NgZone 中使其可用,您就会看到 hasPendingMacroTasks 再次设置为 true。
  2. 您不能仅仅让 SDK 方法(例如登录、注销)在 NgZone 中可用,因为它们需要客户端实例上下文 运行 (我不认为你可以在 Angular 区域之外保存状态(Auth0 客户端实例)并在需要时访问它)。
  3. 每次需要 运行 SDK 功能时,您都无法在 Angular 区域之外创建客户端实例和 运行 SDK 功能,就好像您创建了多个一样客户端实例可能会出错。