当元素定位器找不到其目标时,我可以让 Protractor/Jasmine 命中断点吗?

Can I get Protractor/Jasmine to hit a breakpoint when an element locator fails to find its target?

每次 Protractor 元素定位器失败时,它都会打印错误,并继续沿着我的规范和套件中无休止的级联故障的可怕路径前进。接下来的每个测试都取决于元素定位器找到它的元素,并取决于当前通过的规范。

我想在使用控制台时让正在测试的网页保持打开状态。目标是调试页面的当前状态并调查元素定位器可能无法找到其目标的原因。

我不太担心整个套件失败并在第一个规范失败时退出(我在 --fail-fast 上看到其他答案并在第一个规范失败时停止。)这不是我的方法想带。我想设置一个断点,并在页面 运行.

时检查环境

也许 doThisOnFailure: () => { debugger } 有类似 Jasmine 的选项,我认为这对我有用。

我真的不喜欢在 afterEach 期间使用 spec reporter 执行并检查整个 spec 函数在 Jasmine 环境中失败的 spec 计数的解决方案。我想立即知道元素定位器何时失败,并在失败后立即中断。

也许真正恶心的东西会起作用 $('element').click().catch(() => { debugger })

编辑:请注意,我问的是打破规范,而不是在规范结束时打破。

it('should execute deadly code', function () {
    p.navigation.openStorageConfigTab()
    $$('.bad-selector').get(0).click() /* IMPORTANT: I want to break here */
    p.volume.navigateTo()
})

it('should not execute this spec', function () {
    $$('.bad-selector').get(0).click()
})

和输出

  ✗ should execute deadly code
    - Failed: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By(css selector, .bad-selector)
  ✗ should not execute this spec
    - Failed: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By(css selector, .bad-selector)

我可以向你推荐我使用的方法,希望你能从这里借鉴

总体方法是等到您在浏览器中键入 close/ 命令 url:

await browser.waitForAngularEnabled(false);
await browser.wait(
  async () => {
    let url = await browser.getCurrentUrl();
    return url.includes('close/');
  },
  5 * 60 * 1000,
  'Keep-alive timeout reached, closing the session...'
);

问题是你想什么时候调用它。我在配置文件中使用 onComplete 回调函数的优势。调用时,浏览器仍然可用。因此,一旦所有测试完成,它不会退出 5 分钟,除非我将 close/ 提交到 url 字段。显然这可以是有条件的,通过添加类似 if (DEBUG === true)

的内容

此设置的一个缺点是它会在所有测试完成时被调用,并且您的规范可能已离开出现错误的页面。所以你也可以做的是利用茉莉花记者的优势(如果你使用茉莉花)。粗略地说,你只需要将它添加到你的 onPrepare func:

jasmine.getEnv().addReporter({
    jasmineStarted: function(suiteInfo) {},
    suiteStarted: function(result) {},
    specStarted: function(result) {},
    specDone: async function(spec) {
        if (spec.status === 'failed') {
            await browser.waitForAngularEnabled(false);
            await browser.wait(
                async () => {
                    let url = await browser.getCurrentUrl();
                    return url.includes('close/');
                },
                5 * 60 * 1000,
                'Keep-alive timeout reached, closing the session...'
            );
            await browser.close();
            process.exit(35);
        }
    },
    suiteDone: function(result) {},
    jasmineDone: function(result) {},
});

因此,如果任何 it 块具有 failed 状态,那么它将停止。但是,我还没有测试过,我会留给你。其次,由于您被重定向到不存在的 url close/,我没有考虑其余排队的规范会发生什么,但我相信它仍然对您有用。最坏的情况,你可以玩弄它继续或关闭浏览器实例,只要你理解这个概念

P.S。 我修改了代码以在您键入 close/ 时关闭浏览器,方法是添加

await browser.close();
process.exit(35);

我在以下场景中测试了这段代码:

  • 快乐之路:全部 5 it 都成功了
  • 第二个 it 块的第一个元素查找器失败
  • 第二个 it 块的第二个元素查找器失败

全部通过。代码按预期工作