自动化 End-End 测试 Nightwatch.js 之踩雷笔记:选取文字

如果想要测试的网站是类似具有文字编辑器功用的,像是 ithome 这种类型
假设我们想要将已打过的字体 Highlight 起来,并点击粗体的按钮,像是这样:

https://ithelp.ithome.com.tw/upload/images/20210920/201202507xfdPyu9NQ.png

不知道各位都是怎麽选取,是利用点击两下?点一下拖曳?还是用 shift 加方向键呢?
很可惜的是,Nightwatch 是没有直接对应的指令的。此外,由於前篇提及的 W3C policy,因此不论是点击或是使用 shift,都无法在全部的浏览器上使用。

execute()

Nightwatch 有提供一个有趣的东西:execute
这个指令是用於注入一段 Javascript 的程序码到目前的 frame,也可以带入参数让这个 function 完成更复杂的事(synchronous),官方范例如下:

this.demoTest = function (browser) {
   browser.execute(function(imageData) {
     // resize operation
     return true;
   }, [imageData], function(result) {
     // result.value === true
   });
}

其中的 args array 便是拿来带入的参数,并会依照顺序。

selectElementContent()

有了前面的 execute() 的概念後,就可以利用 Vanilla.js 做出选取文字的功能了。

回到最一开始,选取文字的方式可能是先点一下,接着往右/左移动,最後完成所想要的范围,所以可以利用:

  • document.createRange();
  • document.querySelector(<selector>).selectNodeContents(<el>)
  • window.getSelection();

createRange() 用於定义一个范围,接着使用 selectNodeContents() 全选指定的 DOM 内的文字,最後透过 getSelection() 回传 selection 的范围

整个 function 完成就像这样:

function(selector) {
  const el = document.querySelector(selector);
  const range = document.createRange();
  range.selectNodeContents(el);
  const sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
}, [selector], function(result) {
  callback.call(this, result);
},

或是一样变成客制化的 command:

exports.command = function(selector, callback) {
  callback = callback || function() {};
  this.execute(
    function(selector) {
      const el = document.querySelector(selector);
      const range = document.createRange();
      range.selectNodeContents(el);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
    },
    [selector],
    function(result) {
      callback.call(this, result);
    },
  );
  return this;
};

<<:  资料结构的重要性

>>:  Day_08 有线网路应用(一)

冒险村12 - rescue exception

12 - rescue exception 异常处理在开发过程中时常可见,举例来说 Rails 中找...

DAY 09 - 由後端主动告诉你资料更新 - websocket

回想一下开发经验,当後端资料状态有更新... 不知道大家有没有遇到,在开发的时候,如果状态更新但我们...

D21: 工程师太师了: 第11话

工程师太师了: 第11话 杂记: 前阵子跟朋友讨论到绿色金刚战士。 小时候在看金刚战士的时候, 有个...

[Day 06] DSL 其他和资料库互动的方式

如果只会单一资料表的 CRUD 操作,那麽有很多需求是没有办法满足的。 今天我们来聊聊,怎麽用 DS...

[ 卡卡 DAY 8 ] - React Native 跨平台装置判断

还记得 React Native 可以同时完成 iOS / Android 装置吧? 跨平台装置如...