【问题标题】:Protractor syncing to an Angular page after redirection to Auth0 non-Angular page重定向到 Auth0 非 Angular 页面后量角器同步到 Angular 页面
【发布时间】:2019-08-25 11:17:14
【问题描述】:

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

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

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

请注意,我可以禁用 Angular 同步并且可以让事情正常工作,所以我不会就如何让事情正常工作寻求建议。如果您遇到了特定问题并想出了解决方案,我很乐意听到它。

任何帮助表示赞赏。

【问题讨论】:

  • 我可以说,这是一个措辞出色的问题!

标签: angular oauth protractor


【解决方案1】:

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

首先,手动打开应用,并获得授权。然后在控制台中运行getAllAngularTestabilities()。如果此命令不可用,protractor 不能使用 angular。如果命令成功,查看返回的对象,特别是obj[0]._ngZonehasPendingMacrotaskshasPendingMicrotasks 属性。如果其中任何一个是true,则protractor 无法使用此页面。如果两者都是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 并且是从不重置。正如您在上面解释的那样,这会阻止 Protactor 同步。
【解决方案2】:

我的回答仅供参考:

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

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

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

我研究过在 Angular NgZone 之外运行 createAuth0Client,但事实证明,即使不是不可能,也非常困难:

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

【讨论】:

  • 这正是我总是禁用waitForAngular 的原因。我从来没有运气好。太多的变量会阻止它真正正常工作。禁用然后使用ExpectedConditions 和一些自定义等待功能来确保页面准备就绪会更容易。
猜你喜欢
  • 1970-01-01
  • 2021-01-28
  • 2020-07-30
  • 2017-05-14
  • 1970-01-01
  • 2017-04-27
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
相关资源
最近更新 更多