如何将配置中的对象值与网站上的 href 进行比较

How to compare object values in a config to hrefs on a website

这是我之前发布的问题的后续

在这个问题中,我试图将网站上的 href 值测试为配置文件中存储的内容。

URL: https://wdwthemeparks.com

配置文件(位于Resources/config.json)

{
    "url": "https://wdwthemeparks.com",
    "topMenuNav": {
        "All": "/all/",
        "News": "/news/",
        "Press Releases": "/press/",
        "Rumors": "/rumors/",
        "About": "/about/",
        "Contact": "/contact/",
        "Refurbishments": "/refurbishments/"
    }
}

选择器位于 Objects/header.js

import { Selector, t } from 'testcafe';

class Header {

    constructor() {
        this.topMenuNav = Selector('.top-header-menu')
        this.topMenuNavItem = Selector(this.topMenuNav).find('a');
    }
}

export default new Header();

测试位于 Tests/topMenu.js

import { Selector } from 'testcafe';
import Header from '../Objects/header';

const config = require('../Resources/config.json');

fixture `Check Top Menu`
    .page(config.url)
    .beforeEach( async t => {
        await t.maximizeWindow();
    });

test
    .meta({ desktop: 'true'})
    ('Check Top Menu Items', async t => {

        const topMenuNavKeys = Object.keys(config.topMenuNav);
        const topMenuNavValues = Object.values(config.topMenuNav);

        await t.expect(Header.topMenuNav.visible).ok('Top Menu Nav is NOT visible');
        
        for (const key of topMenuNavKeys) {
            await t.expect(Header.topMenuNavItem.withText(key).exists).ok(`"${key}" Top Menu Nav key does NOT match config`);
          }

// THE PROBLEM I AM HAVING IS HERE IN THIS PART OF THE CODE
          for (const value of topMenuNavValues) {
            await t.expect(Header.topMenuNavItem.getAttribute('href')).contains(value, `"${value}" Top Menu Nav value does NOT match config`);
          }
});

我从 TestCafe 收到以下错误消息:

Running tests in:
 - Chrome 85.0.4183.83 / Windows 10

 Check Top Menu
ReExecutablePromise { _then: [], _fn: [Function], _taskPromise: null }
ReExecutablePromise { _then: [], _fn: [Function], _taskPromise: null }
 × Check Top Menu Items

   1) AssertionError: "/news/" Top Menu Nav value does NOT match config: expected 'https://wdwthemeparks.com/all/' to include '/news/'

      + expected - actual

      -'https://wdwthemeparks.com/all/'
      +undefined


      Browser: Chrome 85.0.4183.83 / Windows 10

         32 |                   await t.expect(Header.topMenuNavItem.withText(key).exists).ok(`"${key}" Top Menu Nav key does NOT match config`);
         33 |             }
         34 |
         35 |             for (const value of topMenuNavValues) {
         36 |                   console.log(Header.topMenuNavItem.getAttribute('href'));
       > 37 |                   await t.expect(await Header.topMenuNavItem.getAttribute('href')).contains(value, `"${value}" Top Menu Nav value does NOT match config`);
         38 |             }
         39 |});
         40 |

         at <anonymous> (C:\Users\J\Repos\wdwthemeparks-automation\Tests\topMenu.js:37:69)



 1/1 failed (7s)

我不确定我做错了什么。

this.topMenuNav = Selector('.top-header-menu')
this.topMenuNavItem = Selector(this.topMenuNav).find('a');

而你的 DOM 是:

<ul id="menu-td-demo-top-menu" class="top-header-menu sf-js-enabled"><li id="menu-item-30278" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-first td-menu-item td-normal-menu menu-item-30278"><a href="https://wdwthemeparks.com/all/">All</a></li>
<li id="menu-item-23037" class="menu-item menu-item-type-custom menu-item-object-custom td-menu-item td-normal-menu menu-item-23037"><a href="/news/">News</a></li>
<li id="menu-item-30297" class="menu-item menu-item-type-custom menu-item-object-custom td-menu-item td-normal-menu menu-item-30297"><a href="/press/">Press Releases</a></li>
<li id="menu-item-23041" class="menu-item menu-item-type-custom menu-item-object-custom td-menu-item td-normal-menu menu-item-23041"><a href="/rumors/">Rumors</a></li>
<li id="menu-item-10635" class="menu-item menu-item-type-post_type menu-item-object-page td-menu-item td-normal-menu menu-item-10635"><a href="https://wdwthemeparks.com/about/">About</a></li>
<li id="menu-item-41" class="menu-item menu-item-type-post_type menu-item-object-page td-menu-item td-normal-menu menu-item-41"><a href="https://wdwthemeparks.com/contact/">Contact</a></li>
<li id="menu-item-30288" class="menu-item menu-item-type-post_type menu-item-object-page td-menu-item td-normal-menu menu-item-30288"><a href="https://wdwthemeparks.com/refurbishments/">Refurbishments</a></li>
</ul>

所以这部分 Header.topMenuNavItem.getAttribute('href') 将始终给您第一个 a 标签,即:

<a href="https://wdwthemeparks.com/all/">All</a>

所以第一次迭代实际上通过了,但是当循环达到/news/值时,它失败了。

基本上你只是迭代你的配置值,而不是你在网站上找到的标签,因为 topMenuNavItem returns 总是相同 tag/selector.

因此您的整个测试文件可能如下所示:

import { Selector } from 'testcafe';
import Header from '../Objects/header';

const config = require('../Resources/config.json');

fixture `Check Top Menu`
    .page(config.url)
    .beforeEach( async t => {
        await t.maximizeWindow();
    });

test
    .meta({ desktop: 'true'})
    ('Check Top Menu Items', async t => {

        const topMenuNavKeys = Object.keys(config.topMenuNav);

        await t.expect(Header.topMenuNav.visible).ok('Top Menu Nav is NOT visible');
        
        for (const key of topMenuNavKeys) {            
            await t.expect(Header.topMenuNavItem.withText(key).exists).ok(`"${key}" Top Menu Nav key does NOT match config`);
            await t.expect(Header.topMenuNavItem.withText(key).getAttribute('href')).contains(config["topMenuNav"][key], `"${config["topMenuNav"][key]}" Top Menu Nav value does NOT match config`);
        }        
});

你应该做的是:

  • 将测试用例简化到最低限度,也许首先去掉不起作用的部分并确认至少有一部分起作用
  • 使用 console.log() 或其他方法提高知名度
  • 验证测试用例的每一行,你需要知道每一行的作用
  • 阅读文档

如果您尝试获取 属性 或调用匹配多个元素的选择器的方法,TestCafe 将使用匹配集中的第一个元素作为目标。由于第二个断言中缺少 withText(itemText),因此您的循环始终断言相同的元素。

expect.contains 断言的 diff 视图有一个错误 (DevExpress/testcafe#5473),因此可以在断言消息中找到线索:

AssertionError: ...: expected 'https://wdwthemeparks.com/all/' to include '/news/'

此外,我不建议在传递选择器属性和方法时使用 await,因为它会禁用 Smart Assertion Query Mechanism。在当前场景下这不是一个交易破坏者,但如果您遵循此建议,您可以在更复杂的场景中显着提高测试稳定性。

以下测试代码似乎对我来说工作正常:

for (const [key, value] of Object.entries(config.topMenuNav)) {
            await t.expect(Header.topMenuNavItem.withText(key).exists).ok(`"${key}" Top Menu Nav key does NOT match config`);

            await t.expect(Header.topMenuNavItem.withText(key).getAttribute('href')).contains(value, `"${value}" Top Menu Nav value does NOT match config`);
        }