переопределение действий для разъема botium webdriverio - PullRequest
0 голосов
/ 12 февраля 2019

edit: изменить тему на переопределение основных функций на botium-webdriverio-connector


Как вызвать нажатие кнопки?

по этой ссылке: https://github.com/codeforequity-at/botium-core/wiki/Botium-Scripting

он говорит, что вам просто нужно поставить

#me
BUTTON btnTitle

, но на самом деле произошло то, что он отправляет литералу BUTTON btnTitle в виде текста боту

not clicking button

для контекста, я реализовал пользовательский WEBDRIVERIO_GETBOTMESSAGE и отправил обратно

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

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Я решил переопределить функцию WEBDRIVERIO_SENDTOBOT.работает на botium-cli 0.0.44, возможно, есть более лучшие решения на более новых версиях.


edit: добавьте больше деталей, исходный код и реализацию

в конце, я переопределяю этифункции 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_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()
    }

}

затем использовать пользовательский заявитель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)

эта установка работает для botium-cli версии 0.0.44, попытался обновить до botium 0.0.45, но получил ошибку на драйвере селена

0 голосов
/ 12 февраля 2019

Инициирование нажатий кнопок является частью Botium Core 1.4.8 .Для нажатий кнопок результат WEBDRIVERIO_GETBOTMESSAGE не учитывается, Botium просто ищет заголовки кнопок (исходный код с селектором селена по умолчанию здесь .

Описанное поведение, которому отправляется литеральный текстбот, скорее всего, из-за более старой версии Botium Core. Пожалуйста, проверьте версию, которую вы используете. Если вы используете версию 1.4.8, включите ведение журнала и дополните свой вопрос выводом журнала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...