代码之家  ›  专栏  ›  技术社区  ›  Rahadian Kumang

botium Webdririo连接器按钮单击

  •  0
  • Rahadian Kumang  · 技术社区  · 6 年前

    编辑:将主题更改为重写botiumwebdririo连接器上的基本函数


    如何触发按钮点击?

    通过此链接: https://github.com/codeforequity-at/botium-core/wiki/Botium-Scripting

    上面说你只需要

    #me
    BUTTON btnTitle
    

    BUTTON btnTitle 作为机器人的文本

    not clicking button

    对于上下文,我实现了一个自定义的webdririo\u GETBOTMESSAGE并将其发回

    {
      "sender": "bot",
      "buttons": [
        {
          "text": "reply1"
        },
        {
          "text": "reply2"
        }
      ],
      "cards": [],
      "media": []
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Rahadian Kumang    6 年前

    我决定重写webdririo_SENDTOBOT函数。 运行在botiumcli0.0.44上,可能在新版本上有更好的解决方案。


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

    最后,我覆盖了这些函数 WEBDRIVERIO_OPENBOT WEBDRIVERIO_SENDTOBOT WEBDRIVERIO_GETBOTMESSAGE 并添加自定义断言器来断言库消息

    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_测试

    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)
    }
    

    /动作/发送

    
    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_响应

    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/画廊

    /**
     * @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()
        }
    
    }
    

    然后使用自定义断言器 testgallery.conda.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)
    

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

        2
  •  0
  •   Florian Treml    6 年前

    触发按钮点击是 Botium Core 1.4.8 . 对于按钮单击,不考虑webdririo\u GETBOTMESSAGE的结果,Botium只查找按钮标题(带有默认selenium选择器的源代码是 here .

    所描述的行为,即文本被发送到bot,很可能是由于botiumcore的旧版本造成的。请检查您正在使用的版本。如果您使用的是版本1.4.8,请 enable logging