botium webdriverio连接器的替代操作 [英] overriding actions for botium webdriverio connector

查看:66
本文介绍了botium webdriverio连接器的替代操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:将主题更改为覆盖botium-webdriverio-connector上的基本功能






如何触发按钮单击?



来自此链接:



对于上下文,我实现了自定义WEBDRIVERIO_GETBOTMESSAGE并将其发送回

  {
发送者:机器人,
按钮:[
{
text: reply1
},
{
text: reply2
}
],
cards:[],
media:[]
}


解决方案

我决定覆盖WEBDRIVERIO_SENDTOBOT函数。
在botium-cli 0.0.44上运行,可能在较新版本上有更好的解决方案。






编辑:添加更多详细信息,源代码和实施



最后,我重写了这些功能 WEBDRIVERIO_OPENBOT WEBDRIVERIO_SENDTOBOT WEBDRIVERIO_GETBOTMESSAGE ,还添加一个自定义断言来断言画廊消息



botium.json

  {
botium:{
Capabilities:{
PROJECTNAME:生产测试,
CONTAINERMODE: webdriverio,
WEBDRIVERIO_OPTIONS:{
desiredCapabilities:{
browserName: chrome
}
},
WEBDRIVERIO_URL:机器人网址,
WEBDRIVERIO_OPENBOT: ./ actions / open_test,
WEBDRIVERIO_IGNOREWELCOMEMESSAGES:1,
WEBDRIVERIO_SENDTOBOT: ./actions/send,
WEBDRIVERIO_GETBOTMESSAGE: ./actions/parse_response,
WEBDRIVERIO_START_SELENIUM:true,
WEBDRIVERIO_START_SELENIUM_OPTS:{
驱动程序 :{{
chrome :{{
version: 2.36
}
}
},
ASSERTERS:[
{
ref :图库,
src: ./asserters/gallery,
global:true
}
]
}
}
}

./ actions / open_test

  module.exports =(容器,浏览器)=> {
返回浏览器
.waitForVisible('#toggle-chat',20000)
.click('#toggle-chat')//单击聊天按钮
.pause(2000 )
.waitForVisible('#get-started',20000)
.click('#get-started')//单击开始,启动聊天
.pause(2000)
}

./ actions / send

  
module.exports =(容器,浏览器,味精)=> {

if(msg.messageText&& msg.messageText!==''&& msg.messageText.indexOf('BUTTON')!== 0){//发送文本消息
返回浏览器
.waitForEnabled('#text-input',10000)
.setValue('#text-input',msg.messageText)
.keys('Enter ')
}否则,如果(msg.messageText.indexOf('BUTTON')=== 0){//如果消息以 BUTTON xxx开头,可以假定测试人员要单击按钮xxx
让buttonTitle = msg.messageText.split('')[1]
如果(!buttonTitle)抛出新的错误('按钮无效(1)')

返回browser.waitForEnabled( `[chatmessagebuttontitle = $ {buttonTitle}]`,10000)
.click(`[chatmessagebuttontitle = $ {buttonTitle}]`)
} else {//未处理,发送人为消息
返回浏览器
.waitForEnabled('#text-input',10000)
.setValue('#text-input','unhandled')
.keys('Enter')
}

}

./ actions / parse_response

  module.exports =(容器,浏览器,elementId)=> {

const botMsg = {发件人:机器人,按钮:[],卡片:[],媒体:[]}

/ **
*
* ...这里解析一些html来填充按钮,媒体和卡
* ...出于安全原因不能放置所有代码,对不起
* ...这里是示例
*
* btw,elementId不是html id属性,因此无法使用# + elementId查询
*找不到Webdriver elementId的文档,但是此页面对
*有帮助http://v4.webdriver.io/api/protocol/elementIdElements.html
*
* /

browser.elementIdElements(elementId,'.bot-bubble')
.then(elements => elements.value)
.then(elements =>
Promise.all(
elements.map(element =>
浏览器.elementIdText(element.ELEMENT).then(text => text.value)

).then(messages => {
//我只需要第一条消息仅此功能对于每个漫游器消息气泡都会调用,因此可以放心地假设,如果(messages.length> 0)botMsg.messageText = messages [0]

//将漫游器响应发送回botium
容器。BotSays(botMsg)
})


}

./ asserter / gallery

  / ** 
* @typedef卡
* @属性{String}图像
* @属性{String}标题
* @property {String}字幕
* @property {Array< String>}按钮
*
* @typedef BotMesage
* @property {Array< Card>}卡
* /

/ **
* @typedef GalleryAssertStepParam
* @property {*} convo
* @property {Array< String>} args
* @property {BotMesage} botMsg
* /

module.exports = class GalleryAsserter {

/ **
*此函数每当parse_response.js完成
* @param {GalleryAssertStepParam} param
* /
assertConvoStep(param){
let args = param.args
let botMsg时,就会调用= param.botMsg

// args必须是一个数组,简单检查
if(!args.concat)return Promise.reject(new Error('Gargery的args不是数组'))
如果(args.length> botMsg.cards.length)返回Promise.reject(新错误('画廊卡的数量不匹配。期望'+ args.length +'。得到'+ botMsg.cards.length))

/ /基本逻辑,以检查从parse_response.js传递的卡是否等于在测试脚本
中编写的卡(对于var i = 0; i< args.length; i ++),{

// ParseGalleryString是一个将任意字符串转换为Card对象的函数
//任意字符串示例:(title = some title,subtitle = some subtitle,image = image url,button = btn1 ,btn2,btn3)
//将转换为JSON {title: some title,subtitle: some subtitle,...}
let card = ParseGalleryString(args [i])
let testcard = botMsg.cards [i]

if(card.image!== testcard.image)返回Promise.reject(new Error(`card [$ {i}]没通过。期望图像为$ {card.image},得到了$ {testcard.image}`))
如果(card.title!== testcard.title)返回Promise.reject(新错误(card [$ {i}]没有通过。期望标题为$ {card.title},得到$ {testcard.title}`)))
if(card.subtitle!== testcard.subtitle)返回Promise.reject(new Error(`card [$ { i}]未通过,期望字幕为$ {card.subtitle},得到$ {testcard.subtitle}`)))

if(card.buttons.length!== testcard.buttons .length)return Promise.reject(new Error(`card [$ {i}]没有通过。期望$ {card.buttons.length}($ {card.buttons.join(',')})按钮,得到$ {testcard.buttons.length}($ {testcard.buttons.join(',')})`)))
if(card.buttons.join('_')!== testcard.buttons。 join('_'))return Promise.reject(new Error(`card [$ {i}]不通过。期望按钮为$ {card.buttons.join(',')}},得到$ {testcard .buttons.join(',')}`))
}

return Promise.resolve()
}

}

然后使用自定义断言
testgallery.convo.txt

 测试图库

#me
显示我一些猫品种

#bot
这是一些猫品种

#bot
画廊(image = http://cat.pic/1 .png,title =阿拉斯加雪橇犬,subtitle =这实际上不是猫,buttons =宠物,提供食物,信息)| (图片= http://cat.pic/2.png,标题=眼镜蛇Kai,副标题=这实际上是电影,按钮=观看,喜欢,不喜欢)

此设置适用于botium-cli版本0.0.44
尝试更新为botium 0.0.45,但硒驱动程序出现了一些错误


edit: change topic to overriding basic functons on botium-webdriverio-connector


How to trigger button click ?

from this link: https://github.com/codeforequity-at/botium-core/wiki/Botium-Scripting

it says that you just need to put

#me
BUTTON btnTitle

but what actually happened is that it sends literal BUTTON btnTitle as text to the bot

for context, i implemented a custom WEBDRIVERIO_GETBOTMESSAGE and send back this

{
  "sender": "bot",
  "buttons": [
    {
      "text": "reply1"
    },
    {
      "text": "reply2"
    }
  ],
  "cards": [],
  "media": []
}

解决方案

i decided to override the WEBDRIVERIO_SENDTOBOT function. running on botium-cli 0.0.44, probably there are better solutions on newer versions.


edit: add more details, source code & implementation

in the end, i override these functions WEBDRIVERIO_OPENBOT WEBDRIVERIO_SENDTOBOT WEBDRIVERIO_GETBOTMESSAGE and also add a custom asserter to assert gallery messages

botium.json

{
  "botium": {
    "Capabilities": {
      "PROJECTNAME": "Production Test",
      "CONTAINERMODE": "webdriverio",
      "WEBDRIVERIO_OPTIONS": {  
        "desiredCapabilities": {
          "browserName": "chrome"      
        }
      },
      "WEBDRIVERIO_URL": "the bot url",
      "WEBDRIVERIO_OPENBOT": "./actions/open_test",
      "WEBDRIVERIO_IGNOREWELCOMEMESSAGES": 1,
      "WEBDRIVERIO_SENDTOBOT": "./actions/send",
      "WEBDRIVERIO_GETBOTMESSAGE": "./actions/parse_response",
      "WEBDRIVERIO_START_SELENIUM": true,
      "WEBDRIVERIO_START_SELENIUM_OPTS": {
        "drivers": {
          "chrome": {
            "version": "2.36"
          }
        }
      },
      "ASSERTERS": [
        {
          "ref": "GALLERY",
          "src": "./asserters/gallery",
          "global": true
        }
      ]
    }
  }
}

./actions/open_test

module.exports = (container, browser) => {
    return browser
        .waitForVisible('#toggle-chat', 20000)
        .click('#toggle-chat') // click chat button
        .pause(2000)
        .waitForVisible('#get-started', 20000)
        .click('#get-started') // click get started, initiate the chat
        .pause(2000)
}

./actions/send


module.exports = (container, browser, msg) => {

    if (msg.messageText && msg.messageText !== '' && msg.messageText.indexOf('BUTTON') !== 0) { // send text message
        return browser
            .waitForEnabled('#text-input', 10000)
            .setValue('#text-input', msg.messageText)
            .keys('Enter')
    } else if (msg.messageText.indexOf('BUTTON') === 0) { // if message started with "BUTTON xxx", safe to assume the tester want to click button xxx
        let buttonTitle = msg.messageText.split(' ')[1]
        if (!buttonTitle) throw new Error('BUTTON invalid (1)')

        return browser.waitForEnabled(`[chatmessagebuttontitle="${ buttonTitle }"]`, 10000)
        .click(`[chatmessagebuttontitle="${ buttonTitle }"]`)
    } else { // unhandled, send arbitary message
        return browser
            .waitForEnabled('#text-input', 10000)
            .setValue('#text-input', 'unhandled')
            .keys('Enter')
    }

}

./actions/parse_response

module.exports = (container, browser, elementId) => {

    const botMsg = { sender: 'bot', buttons: [], cards: [], media: [] }

    /**
    *
    * ... parsing some html here to populate buttons, media and cards
    * ... can't put all the code for security reasons, sorry
    * ... here are example
    *
    * btw, elementId is NOT an html id attribute, so cannot query with "#" + elementId
    * cannot find documentation for webdriver elementId, but this page helps
    * http://v4.webdriver.io/api/protocol/elementIdElements.html
    *
    */

    browser.elementIdElements(elementId, '.bot-bubble')
    .then(elements => elements.value)
    .then(elements => 
        Promise.all(
            elements.map(element => 
                browser.elementIdText(element.ELEMENT).then(text => text.value)
            )
        ).then(messages => {
            // i only need the first message, also this function only called for each bot message bubble, so safe to assume there is only 1 message
            if (messages.length > 0) botMsg.messageText = messages[0] 

            // send the bot response back to botium
            container.BotSays(botMsg)
        })
    )

}

./asserter/gallery

/**
 * @typedef Card
 * @property {String} image
 * @property {String} title
 * @property {String} subtitle
 * @property {Array<String>} buttons
 * 
 * @typedef BotMesage
 * @property {Array<Card>} cards
 */

/**
 * @typedef GalleryAssertStepParam
 * @property {*} convo
 * @property {Array<String>} args
 * @property {BotMesage} botMsg
 */

module.exports = class GalleryAsserter {

    /**
     * this function is called whenever parse_response.js finishes
     * @param {GalleryAssertStepParam} param
     */
    assertConvoStep(param) {
        let args = param.args
        let botMsg = param.botMsg

        // args needs to be an array, simple check
        if (!args.concat) return Promise.reject(new Error('args for GALLERY is not an array'))
        if (args.length > botMsg.cards.length) return Promise.reject(new Error('number of gallery cards doesnt match. expecting ' + args.length +'. Got ' + botMsg.cards.length))

        // basic logic to check if the card that is passed from parse_response.js is equals to card that is written in test scripts 
        for (var i = 0; i < args.length; i++) {

            // ParseGalleryString is a function that convert arbitary string to a Card object
            // example of the arbitary string: "( title=some title, subtitle= some subtitle, image=image url, buttons=btn1, btn2, btn3 )"
            // will be converted to JSON { title: "some title", subtitle: "some subtitle", ... }
            let card = ParseGalleryString(args[i])
            let testcard = botMsg.cards[i]

            if (card.image !== testcard.image) return Promise.reject(new Error(`card[${i}] doesn't pass. expecting image to be ${ card.image }, got ${ testcard.image }`))
            if (card.title !== testcard.title) return Promise.reject(new Error(`card[${i}] doesn't pass. expecting title to be ${ card.title }, got ${ testcard.title }`))
            if (card.subtitle !== testcard.subtitle) return Promise.reject(new Error(`card[${i}] doesn't pass. expecting subtitle to be ${ card.subtitle }, got ${ testcard.subtitle }`))

            if (card.buttons.length !== testcard.buttons.length) return Promise.reject(new Error(`card[${i}] doesn't pass. expecting ${ card.buttons.length }(${card.buttons.join(', ')}) buttons, got ${ testcard.buttons.length }(${testcard.buttons.join(', ')})`))
            if (card.buttons.join('_') !== testcard.buttons.join('_')) return Promise.reject(new Error(`card[${i}] doesn't pass. expecting buttons to be ${ card.buttons.join(', ') }, got ${ testcard.buttons.join(', ') }`))
        }

        return Promise.resolve()
    }

}

then to use the custom asserter testgallery.convo.txt

Test Gallery

#me
show me some cat breeds

#bot
here are some cat breeds

#bot
GALLERY (image=http://cat.pic/1.png, title=Alaskan Malmute, subtitle=This is actually not a cat, buttons=Pet, Give Food, Info) | (image=http://cat.pic/2.png, title=Cobra Kai, subtitle=This is actually a movie, buttons=Watch, Like, Dislike)

this setup works for botium-cli version 0.0.44 tried to update to botium 0.0.45 but got some error on selenium driver

这篇关于botium webdriverio连接器的替代操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆