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

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

这是我先前发布的问题here

的后续活动

在这个问题中,我试图将网站上的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: [],_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)

我不确定自己做错了什么。

解决方法

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

expect.contains断言的差异视图有一个错误(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`);
        }
,
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总是返回相同的标记/选择器。

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

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()或其他方法来提高可见度
  • 验证测试用例的每一行,您需要知道每一行的作用
  • 阅读文档

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?