微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Scenario测试中的代码有效,页面对象中的相同代码失败CodeceptJS

如何解决Scenario测试中的代码有效,页面对象中的相同代码失败CodeceptJS

我有一个使用Puppeteer的CodeceptJS项目,并且只是尝试在React站点中使用表。我相信在测试场景中可以使用完全相同的代码,但是效果很好,但是当我将相同的代码放入页面对象方法中时,它就会失败。

测试场景

Scenario('Check Box of specific table row',async (I,loginAs,navFragment) => {
  loginAs('bob');
  navFragment.expandAdmin();
  navFragment.toSites();
  let msg = await I.grabTextFrom(`tbody tr:nth-child(1) td:nth-child(2)`);
  I.assertEqual('IDH',msg);
  within(`tbody tr:nth-child(1) td:nth-child(1) span span`,() => {
    I.click('input');
  });
  I.wait(5);
});

在测试场景中,我很难对子位置进行编码,以打中我要跟踪的行和列。

我的页面对象类中的方法如下所示。

async test() {
    const totalRows = await I.grabAttributeFrom('tbody tr');
    I.say('Total Rows: ' + totalRows.length);

    for (let i = 1; i < totalRows.length; i++) {
      I.say('Made it into the for loop')
      const str = await I.grabTextFrom(`tbody tr:nth-child(${i}) td:nth-child(2)`);
      I.say('String value from table is: ' + str);
      if (str === 'IDH') {
        I.say('Match found in row: ' + i);
        within(`tbody tr:nth-child(1) td:nth-child(1) span span`,() => {
          I.click('input');
        });
      }
    }
  }

如图所示,即使我的意图是使用循环并遍历表格的每一行,但我目前仍将硬编码的点击的子位置用于测试。

我已经确定我的for循环正在导致/导致此问题。如果我将其取出并在页面对象中使用以下内容,它将仍然失败。

这是经过修改的PO方法

async test() {
    const totalRows = await I.grabAttributeFrom('tbody tr');
    I.say('Total Rows: ' + totalRows.length);

    for (let i = 1; i < totalRows.length; i++) {
      I.say('Made it into the for loop')
      const str = await I.grabTextFrom(`tbody tr:nth-child(${i}) td:nth-child(2)`);
      I.say('String value from table is: ' + str);
      I.wait(2);
      // if (str === 'IDR') {
      //   I.say('Match found in row: ' + i);
      //   within(`tbody tr:nth-child(1) td:nth-child(1) span span`,() => {
      //     I.click('input');
      //   });
      //   break;
      // }
    }
  }

这里唯一的目标是遍历一个表中的4行,并打印出为每行指定的值。

进入第二次迭代时,会发生以下错误

PS C:\ projects \ csPptr \ ipt> npx codeceptjs运行./src/tests/_sandBox.js --steps --verbose
CodeceptJS v2.6.10 使用测试根目录“ C:\ projects \ csPptr \ ipt” 帮手:Puppeteer,ChaiWrapper,TableHelper,ShowIPhone 插件:retryFailedStep,自动登录

SandBox to play around in --
    [1] Starting recording promises
    Emitted | suite.before ([object Object])
  Table check ALL
    Emitted | test.before ([object Object])
    Emitted | test.start ([object Object])
    Emitted | step.before (I am on page "/login")
    Emitted | step.after (I am on page "/login")
    Emitted | step.before (I fill field "#username","bob@infdig.com")
    Emitted | step.after (I fill field "#username","bob@infdig.com")
    Emitted | step.before (I fill field "#password",*****)
    Emitted | step.after (I fill field "#password",*****)
    Emitted | step.before (I click "Sign in")
    Emitted | step.after (I click "Sign in")
    Emitted | step.before (I grab cookie )
    Emitted | step.after (I grab cookie )
    Emitted | step.before (I click "li[id="resources.admin.name"]")
    Emitted | step.after (I click "li[id="resources.admin.name"]")
    Emitted | step.before (I click "Sites")
    Emitted | step.after (I click "Sites")
    Emitted | step.before (I grab attribute from "tbody tr")
    Emitted | step.after (I grab attribute from "tbody tr")
    Emitted | step.before (I wait 5)
    Emitted | step.after (I wait 5)
    Emitted | step.start (I am on page "/login")
    Object: login
      I am on page "/login"
      » [Url] https://infinity-production-tracker-qa.web.app/#/login
      » [browser:Warning] 
It looks like you're using the development build of the Firebase JS SDK.
When deploying Firebase apps to production,it is advisable to only import
the individual SDK components you intend to use.

For the module builds,these are available in the following manner
(replace <PACKAGE> with the name of a component - i.e. auth,database,etc):

Commonjs Modules:
const firebase = require('firebase/app');
require('firebase/<PACKAGE>');

ES Modules:
import firebase from 'firebase/app';
import 'firebase/<PACKAGE>';

Typescript:
import * as firebase from 'firebase/app';
import 'firebase/<PACKAGE>';
JSHandle:
It looks like you're using the development build of the Firebase JS SDK.
When deploying Firebase apps to production,etc):

Commonjs Modules:
const firebase = require('firebase/app');
require('firebase/<PACKAGE>');

ES Modules:
import firebase from 'firebase/app';
import 'firebase/<PACKAGE>';

Typescript:
import * as firebase from 'firebase/app';
import 'firebase/<PACKAGE>';

      » [browser:Log] JSHandle@objectJSHandle@object
      » [browser:Log] custom routes JSHandle@objectJSHandle:custom routes JSHandle@object
      » [browser:Log] Registering custom data provider for resource: stationadoptJSHandle:Registering custom data provider for

资源:stationadopt »[浏览器:日志] FrameworkApp初始化JSHandle @ objectJSHandle:FrameworkApp初始化JSHandle @ object »[浏览器:日志]节点环境是生产JSHandle:节点环境是生产 »[浏览器:日志]注册服务人员JSHandle:注册服务人员 »[浏览器:日志]注册服务人员级别2 JSHandle:注册服务人员级别2 »[浏览器:详细] [DOM]输入元素应具有自动完成属性(建议:“用户名”):(更多信息: https:// googl / 9p2vKq)%o »[浏览器:日志]注册服务人员级别3 JSHandle:注册服务人员级别3 »[浏览器:日志] JSHandle @ objectJSHandle @ object »[浏览器:日志]内容被缓存供脱机使用。JSHandle:内容被缓存供脱机使用。 »[浏览器:日志] JSHandle @ objectJSHandle @ object »[浏览器:日志] JSHandle @ objectJSHandle @ object 发射step.passed(我在页面“ /登录”上) 发射step.finish(我在页面“ /登录”上) 发射step.start(我填写了字段“ #username”,“ bob@infdig.com”) 我填写“ #username”,“ bob@infdig.com”字段 发射step.passed(我填写字段“ #username”,“ bob@infdig.com”) 发射step.finish(我填写字段“ #username”,“ bob@infdig.com”) 发射step.start(我填写字段“ #password”,*****) 我填写“ #password”字段,***** 发射step.passed(我填写字段“ #password”,*****) 发射step.finish(我填写字段“ #password”,*****) 发射step.start(我单击“登录”) 我点击“登录” 发射step.passed(我单击“登录”) 发射step.finish(我单击“登录”) 发射step.start(我抓取cookie) 我抓饼干 发射step.passed(我抓饼干) 发射step.finish(我抓饼干) 发射step.start(我单击“ li [id =“ resources.admin.name”]“) 我单击“ li [id =“ resources.admin.name”]“ [1]重试...尝试#2 »[网址] https://infinity-production-tracker-qa.web.app/#/ »[浏览器:日志] FrameworkAppLayout初始化JSHandle:FrameworkAppLayout初始化 »[浏览器:日志]构建菜单JSHandle:构建菜单 »[浏览器:日志]菜单结构JSHandle @ objectJSHandle:菜单结构JSHandle @ object »[浏览器:日志]加载的本地存储数据JSHandle @ objectJSHandle:加载的本地存储数据JSHandle @ object [1]重试...尝试#3 »[浏览器:日志]构建菜单JSHandle:构建菜单 »[浏览器:日志]菜单结构JSHandle @ objectJSHandle:菜单结构JSHandle @ object 发射step.passed(我单击“ li [id =“ resources.admin.name”]“) 发射step.finish(我单击“ li [id =“ resources.admin.name”]“) 发射step.start(我单击“站点”) 我点击“站点” »[网址] https://infinity-production-tracker-qa.web.app/#/site »[浏览器:日志] FrameworkAppLayout初始化JSHandle:FrameworkAppLayout初始化 »[浏览器:日志]数据提供者工厂请求:GET_LIST站点[对象对象] JSHandle:数据提供者工厂请求:GET_LIST站点 [对象对象] »[浏览器:日志]使用认提供程序JSHandle:使用认提供程序 发射step.passed(我单击“站点”) 发射step.finish(我单击“站点”) 发射step.start(我从“ tbody tr”获取属性) 我从“ tbody tr”中获取属性 [1]重试...尝试#2 [1]重试...尝试#3 发射step.passed(我从“ tbody tr”获取属性) 发射step.finish(我从“ tbody tr”获取属性) 发射step.before(我从“ tbody tr:nth-​​child(1)td:nth-​​child(2)”中获取文本) 发射step.after(我从“ tbody tr:nth-​​child(1)td:nth-​​child(2)”中获取文本) 发射step.start(我等5) 我等5 »[浏览器:日志] FrameworkAppLayout初始化JSHandle:FrameworkAppLayout初始化 发射step.passed(我等5) 发射step.finish(我等待5) 发射test.passed([对象对象]) 发射test.finish([对象对象]) √12968毫秒内确定

    Emitted | step.comment (Total Rows: 4)
   Total Rows: 4
    Emitted | step.comment (Made it into the for loop)
   Made it into the for loop
    Emitted | step.start (I grab text from "tbody tr:nth-child(1) td:nth-child(2)")
    sitesPage: test
      I grab text from "tbody tr:nth-child(1) td:nth-child(2)"
    Emitted | test.after ([object Object])
    Emitted | step.passed (I grab text from "tbody tr:nth-child(1) td:nth-child(2)")
    Emitted | step.finish (I grab text from "tbody tr:nth-child(1) td:nth-child(2)")
    Emitted | step.before (I wait 2)
    Emitted | step.after (I wait 2)
    Emitted | step.before (I grab text from "tbody tr:nth-child(2) td:nth-child(2)")
    Emitted | step.after (I grab text from "tbody tr:nth-child(2) td:nth-child(2)")
    Emitted | step.comment (String value from table is: IDH)
   String value from table is: IDH
    Emitted | step.start (I wait 2)
      I wait 2
    Emitted | suite.after ([object Object])
    Emitted | step.passed (I wait 2)
    Emitted | step.finish (I wait 2)
    Emitted | step.comment (Made it into the for loop)
   Made it into the for loop
    Emitted | step.start (I grab text from "tbody tr:nth-child(2) td:nth-child(2)")
      I grab text from "tbody tr:nth-child(2) td:nth-child(2)"
    [1] retrying... Attempt #2
    [1] retrying... Attempt #3
    [1] retrying... Attempt #4
    [1] retrying... Attempt #5
    [1] retrying... Attempt #6
    [1] Error | TypeError: Cannot read property '$$' of null
    Emitted | step.Failed (I grab text from "tbody tr:nth-child(2) td:nth-child(2)")
    Emitted | step.finish (I grab text from "tbody tr:nth-child(2) td:nth-child(2)")
    [1] Error | TypeError: Cannot read property '$$' of null
    Emitted | test.Failed ([object Object])
  × "after all" hook: codeceptjs.afterSuite for "More goofing around" in 6665ms
    [1] Error | TypeError: Cannot read property '$$' of null
TypeError: Cannot read property '$$' of null
(node:27404) UnhandledPromiseRejectionWarning: Cannot read property '$$' of nullTypeError: Cannot read property '$$' of null
    at findElements (node_modules\codeceptjs\lib\helper\Puppeteer.js:2189:42)
    at Puppeteer._locate (node_modules\codeceptjs\lib\helper\Puppeteer.js:776:12)
    at async Puppeteer.grabTextFrom (node_modules\codeceptjs\lib\helper\Puppeteer.js:1535:17)
(node:27404) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async

没有捕获块的功能,或者拒绝了原本是 没有处理 。抓住()。要在未处理的承诺拒绝时终止节点进程,请使用CLI标志--unhandled-rejections=strict(请参见 https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。 (拒绝ID:7) (节点:27404)[DEP0018] DeprecationWarning:已弃用未处理的承诺拒绝。将来,承诺拒绝 未处理将以非零退出终止Node.js进程 代码

-- FAILURES:

  1) SandBox to play around in
       "after all" hook: codeceptjs.afterSuite for "More goofing around":
     Cannot read property '$$' of null
  ypeError: Cannot read property '$$' of null
      at findElements (node_modules\codeceptjs\lib\helper\Puppeteer.js:2189:42)
      at Puppeteer._locate (node_modules\codeceptjs\lib\helper\Puppeteer.js:776:12)
      at async Puppeteer.grabTextFrom (node_modules\codeceptjs\lib\helper\Puppeteer.js:1535:17)


  FAIL  | 1 passed,1 Failed   // 21s
    Emitted | global.result ([object Object])
    Emitted | global.after ([object Object])
PS C:\projects\csPptr\ipt>

如果有任何人可以帮助我理解这一点,以便我能够克服这些问题,我将不胜感激。

谢谢! 鲍勃

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