Unable to get any text from elementId(parser_response)

Hi @Florian ,

I’m trying to automate a live chatbot. I’m using Botium-cli along with webdriverio and selenium server. I think I have followed the right setup steps. The only problem I’m facing is I’m not getting any output from parser_response.

E:\botium_urc>botium-cli run -v --convos .\setup.convo.txt
  botium-cli Using Botium configuration file ./botium.json +0ms
  botium-cli-run command options: {
  botium-cli-run   _: [ 'run' ],
  botium-cli-run   v: true,
  botium-cli-run   verbose: true,
  botium-cli-run   convos: [ '.\\setup.convo.txt' ],
  botium-cli-run   C: [ '.\\setup.convo.txt' ],
  botium-cli-run   config: './botium.json',
  botium-cli-run   c: './botium.json',
  botium-cli-run   output: 'spec',
  botium-cli-run   testsuitename: 'Botium Test-Suite',
  botium-cli-run   n: 'Botium Test-Suite',
  botium-cli-run   expandutterances: false,
  botium-cli-run   expandscriptingmemory: false,
  botium-cli-run   timeout: 60,
  botium-cli-run   '$0': 'C:\\Users\\svenugopal\\AppData\\Roaming\\npm\\node_modules\\botium-cli\\bin\\botium-cli.js'
  botium-cli-run } +0ms
  botium-cli-run Mocha Reporter "spec", options: undefined +2ms
  botium-core-BotDriver Loaded Botium configuration files E:\botium_urc\botium.json +0ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) found filenames: setup.convo.txt +0ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) found convos:
  botium-core-ScriptingProvider  1 osm_tv_setup ({ convoDir: '.', filename: 'setup.convo.txt' }): Line 3: #bot - Hi I'm your smart home assistant. I can help you discover and control your devices. Tap below to get started. | Line 6: #me - reset configuration | Line 9: #bot - Are you sure you want to reset? | Line 12: #me - yes | Line 15: #bot - Sure. | Line 18: #me - setup my tv | Line 21: #bot - What is the brand? | Line 24: #me - samsung | Line 27: #bot - OK! Make sure your samsung TV is on. Say OK when ready | Line 30: #me - ok | Line 33: #bot - Trying VOLUME UP now. Did it work ?. | Line 36: #me - yes | Line 39: #bot - Do you see your dish network Guide ? | Line 42: #me - yes | Line 45: #bot - You are all set! +12ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) found utterances:
  botium-core-ScriptingProvider  none +2ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) found partial convos:
  botium-core-ScriptingProvider  none +1ms
  botium-core-ScriptingProvider ReadConvosFromDirectory(.) scripting memories:
  botium-core-ScriptingProvider  none +0ms
  botium-cli-run ready reading convos (1), expanding convos ... +596ms
  botium-core-ScriptingProvider ExpandConvos - Using utterances expansion mode: all +4ms
  botium-cli-run ready expanding convos and utterances, number of test cases: (1). +50ms
  botium-cli-run adding test case osm_tv_setup (from: { convoDir: '.', filename: 'setup.convo.txt' }) +8ms


  Botium Test-Suite
  botium-core-BotDriver Build - Botium Core Version: 1.11.2 +668ms
  botium-core-BotDriver Build - Capabilites: {
  botium-core-BotDriver   PROJECTNAME: 'WebdriverIO Plugin Sample',
  botium-core-BotDriver   TESTSESSIONNAME: 'Botium Test Session',
  botium-core-BotDriver   TESTCASENAME: 'Botium Test Case',
  botium-core-BotDriver   TEMPDIR: 'botiumwork',
  botium-core-BotDriver   CLEANUPTEMPDIR: true,
  botium-core-BotDriver   WAITFORBOTTIMEOUT: '60000',
  botium-core-BotDriver   SIMULATE_WRITING_SPEED: false,
  botium-core-BotDriver   SIMPLEREST_PING_RETRIES: 6,
  botium-core-BotDriver   SIMPLEREST_PING_TIMEOUT: 10000,
  botium-core-BotDriver   SIMPLEREST_PING_VERB: 'GET',
  botium-core-BotDriver   SIMPLEREST_PING_UPDATE_CONTEXT: true,
  botium-core-BotDriver   SIMPLEREST_STOP_RETRIES: 6,
  botium-core-BotDriver   SIMPLEREST_STOP_TIMEOUT: 10000,
  botium-core-BotDriver   SIMPLEREST_STOP_VERB: 'GET',
  botium-core-BotDriver   SIMPLEREST_START_RETRIES: 6,
  botium-core-BotDriver   SIMPLEREST_START_TIMEOUT: 10000,
  botium-core-BotDriver   SIMPLEREST_START_VERB: 'GET',
  botium-core-BotDriver   SIMPLEREST_POLL_VERB: 'GET',
  botium-core-BotDriver   SIMPLEREST_POLL_INTERVAL: 1000,
  botium-core-BotDriver   SIMPLEREST_POLL_UPDATE_CONTEXT: true,
  botium-core-BotDriver   SIMPLEREST_METHOD: 'GET',
  botium-core-BotDriver   SIMPLEREST_IGNORE_EMPTY: true,
  botium-core-BotDriver   SIMPLEREST_TIMEOUT: 10000,
  botium-core-BotDriver   SIMPLEREST_EXTRA_OPTIONS: {},
  botium-core-BotDriver   SIMPLEREST_STRICT_SSL: true,
  botium-core-BotDriver   SIMPLEREST_INBOUND_UPDATE_CONTEXT: true,
  botium-core-BotDriver   SIMPLEREST_CONTEXT_MERGE_OR_REPLACE: 'MERGE',
  botium-core-BotDriver   SCRIPTING_TXT_EOL: '\n',
  botium-core-BotDriver   SCRIPTING_XLSX_EOL_WRITE: '\r\n',
  botium-core-BotDriver   SCRIPTING_XLSX_HASHEADERS: true,
  botium-core-BotDriver   SCRIPTING_CSV_SKIP_HEADER: true,
  botium-core-BotDriver   SCRIPTING_CSV_QUOTE: '"',
  botium-core-BotDriver   SCRIPTING_CSV_ESCAPE: '"',
  botium-core-BotDriver   SCRIPTING_NORMALIZE_TEXT: true,
  botium-core-BotDriver   SCRIPTING_ENABLE_MEMORY: false,
  botium-core-BotDriver   SCRIPTING_ENABLE_MULTIPLE_ASSERT_ERRORS: false,
  botium-core-BotDriver   SCRIPTING_MATCHING_MODE: 'regexp',
  botium-core-BotDriver   SCRIPTING_UTTEXPANSION_MODE: 'all',
  botium-core-BotDriver   SCRIPTING_UTTEXPANSION_RANDOM_COUNT: 1,
  botium-core-BotDriver   SCRIPTING_UTTEXPANSION_NAMING_MODE: 'justLineTag',
  botium-core-BotDriver   SCRIPTING_UTTEXPANSION_NAMING_UTTERANCE_MAX: '16',
  botium-core-BotDriver   SCRIPTING_MEMORYEXPANSION_KEEP_ORIG: false,
  botium-core-BotDriver   ASSERTERS: [],
  botium-core-BotDriver   LOGIC_HOOKS: [],
  botium-core-BotDriver   USER_INPUTS: [],
  botium-core-BotDriver   SECURITY_ALLOW_UNSAFE: true,
  botium-core-BotDriver   CONTAINERMODE: 'webdriverio',
  botium-core-BotDriver   WEBDRIVERIO_OPTIONS: { capabilities: { browserName: 'chrome' } },
  botium-core-BotDriver   WEBDRIVERIO_URL: 'https://chatboturl.net/',
  botium-core-BotDriver   WEBDRIVERIO_OPENBOT: `module.exports = (async () => { const startChat1 = await container.findElement("//input[@id='username-input']"); await startChat1.waitForClickable({ timeout: 20000 }); await startChat1.setValue('emailid@gmail.com'); const startChat3 = await container.findElement("//input[@id='password-input']"); await startChat3.waitForClickable({ timeout: 20000 }); await startChat3.setValue('password'); const startChat4 = await container.findElement("//div[@id='normal-login-button']"); await startChat4.waitForClickable({ timeout: 20000 }); await startChat4.click(); await new Promise(r => setTimeout(r, 10000));const startChat5 = await container.findElement("//div[@class='btn btn-primary btn-sm'][text()='<deviceId>']"); await startChat5.waitForClickable({ timeout: 40000 }); await startChat5.click(); })`,
  botium-core-BotDriver   WEBDRIVERIO_INPUT_ELEMENT: "//input[@id='btn-input']",
  botium-core-BotDriver   WEBDRIVERIO_INPUT_ELEMENT_SENDBUTTON: '.chat-button',
  botium-core-BotDriver   WEBDRIVERIO_OUTPUT_ELEMENT: "//div[@class='messages msg_receive']/span",
  botium-core-BotDriver   WEBDRIVERIO_GETBOTMESSAGE: './parse_response',
  botium-core-BotDriver   WEBDRIVERIO_OUTPUT_ELEMENT_HASH: 'TEXT',
  botium-core-BotDriver   WEBDRIVERIO_OUTPUT_ELEMENT_HASH_SELECTOR: "//div[@class='messages msg_receive']/span",
  botium-core-BotDriver   WEBDRIVERIO_IGNOREWELCOMEMESSAGES: 1,
  botium-core-BotDriver   WEBDRIVERIO_IGNOREUPFRONTMESSAGES: false,
  botium-core-BotDriver   CONFIG: './botium.json'
  botium-core-BotDriver } +3ms
  botium-core-BotDriver Build - Sources : { LOCALPATH: '.', GITPATH: 'git', GITBRANCH: 'master', GITDIR: '.' } +17ms
  botium-core-BotDriver Build - Envs : { IS_BOTIUM_CONTAINER: true } +7ms
  botium-connector-PluginConnectorContainer-helper Botium plugin botium-connector-webdriverio loaded. Plugin version is 0.3.9 +0ms
  botium-connector-webdriverio Validate called +0ms
  botium-connector-webdriverio Loaded Capability WEBDRIVERIO_OPENBOT function as javascript +26ms
  botium-connector-webdriverio Loaded Capability WEBDRIVERIO_GETBOTMESSAGE function from file E:\botium_urc\parse_response +3ms
  botium-connector-webdriverio Build called +4ms
  botium-connector-webdriverio Start called +16ms
  botium-connector-webdriverio Webdriver Options: {"capabilities":{"browserName":"chrome"},"logLevel":"silent"} +0ms
  botium-connector-webdriverio URL https://chatboturl.net/ opened, page title: IdentityServer +29s
  botium-connector-webdriverio URL https://chatboturl.net/ opened, deleted local storage +37ms
  botium-connector-webdriverio URL https://chatboturl.net/ opened, deleted session storage +33ms
  botium-connector-webdriverio Running WEBDRIVERIO_OPENBOT function from inline javascript ... +3ms
  botium-connector-webdriverio trying original waitForClickable function +137ms
  botium-connector-webdriverio trying original waitForClickable function +644ms
  botium-connector-webdriverio trying original waitForClickable function +369ms
  botium-connector-webdriverio trying original waitForClickable function +10s
  botium-connector-webdriverio Waiting for 1 welcome messages (will be ignored) ... +279ms
  botium-connector-webdriverio Found new bot response element, id ed3b5c8f-0ed8-481c-80d7-c204b1f39ad4, hashKey Please select a device to get started. +211ms
  botium-connector-webdriverio Running WEBDRIVERIO_GETBOTMESSAGE function from file E:\botium_urc\parse_response ... +11ms
ed3b5c8f-0ed8-481c-80d7-c204b1f39ad4
  botium-connector-webdriverio Found new bot response element, id eda47c2e-7a54-450f-b70b-cf7d7cbcd864, hashKey Hi I'm your smart home assistant. I can help you discover and control your devices. Tap below to get started. +4s
  botium-connector-webdriverio Running WEBDRIVERIO_GETBOTMESSAGE function from file E:\botium_urc\parse_response ... +5ms
eda47c2e-7a54-450f-b70b-cf7d7cbcd864
    1) "before each" hook for "osm_tv_setup"
  botium-connector-webdriverio Stop called +15s
  botium-connector-webdriverio Clean called +2s
  botium-connector-BaseContainer Cleanup rimrafing temp dir E:\botium_urc\botiumwork\WebdriverIO Plugin Sample 20210519 122124 Mu1pu +0ms


  0 passing (1m)
  1 failing

  1) Botium Test-Suite
       "before each" hook for "setup":
     Error: Timeout of 60000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
      at listOnTimeout (internal/timers.js:554:17)
      at processTimers (internal/timers.js:497:7)

Botium.json:

{
  "botium": {
    "Capabilities": {
      "PROJECTNAME": "WebdriverIO Plugin Sample",
      "CONTAINERMODE": "webdriverio",
      "WEBDRIVERIO_OPTIONS": {
        "capabilities": {
          "browserName": "chrome" 
        }
      },
      "WEBDRIVERIO_URL": "https://chatboturl.net/",
	  "WEBDRIVERIO_OPENBOT": "module.exports = (async () => { const startChat1 = await container.findElement(\"//input[@id='username-input']\"); await startChat1.waitForClickable({ timeout: 20000 }); await startChat1.setValue('mailid@gmail.com'); const startChat3 = await container.findElement(\"//input[@id='password-input']\"); await startChat3.waitForClickable({ timeout: 20000 }); await startChat3.setValue('password'); const startChat4 = await container.findElement(\"//div[@id='normal-login-button']\"); await startChat4.waitForClickable({ timeout: 20000 }); await startChat4.click(); await new Promise(r => setTimeout(r, 10000));const startChat5 = await container.findElement(\"//div[@class='btn btn-primary btn-sm'][text()='<deviceid>']\"); await startChat5.waitForClickable({ timeout: 40000 }); await startChat5.click(); })",
      "WEBDRIVERIO_INPUT_ELEMENT": "//input[@id='btn-input']",
	  "WEBDRIVERIO_INPUT_ELEMENT_SENDBUTTON": ".chat-button",
      "WEBDRIVERIO_OUTPUT_ELEMENT": "//div[@class='messages msg_receive']/span",
	  "WEBDRIVERIO_GETBOTMESSAGE": "./parse_response",
	  "WEBDRIVERIO_OUTPUT_ELEMENT_HASH": "TEXT",
	  "WEBDRIVERIO_OUTPUT_ELEMENT_HASH_SELECTOR": "//div[@class='messages msg_receive']/span",
	  "WAITFORBOTTIMEOUT": "60000",
	  "WEBDRIVERIO_IGNOREWELCOMEMESSAGES": 1,
	  "WEBDRIVERIO_IGNOREUPFRONTMESSAGES": "false",
      "SCRIPTING_MATCHING_MODE": "regexp",
	  "SIMPLEREST_IGNORE_EMPTY": "true"
	}
	}
}

parser_response:

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

    const botMsg = { sender: 'bot', buttons: [], cards: [], media: [] }
	
	console.log(elementId.elementId);
	
	
    browser.elementIdElements(elementId, "Messages_2__MessageId")
    .then(elements => elements.value)
    .then(elements => 
        Promise.all(
            elements.map(element => 
                browser.elementIdText(element.ELEMENT).then(text => text.value)
            )
        ).then(messages => {
            if (messages.length > 0) botMsg.messageText = messages[0] 

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

PS: Sorry if there are any basic coding errors. I’m new to Botium and java :slightly_smiling_face:

Thanks,

Yes you followed the right steps. From a first look at your code, I think there are at least two issues:

  • the function should either be async or return a Promise
  • the element selector Messages_2__MessageId looks invalid

By the way, the the code seems pretty useless, as it is just extracting some text - this should actually work without any code-level customizations.

1 Like

Hey, Thanks for the quick reply.
Is there any sample code template available that I can follow?

To my knowledge, for the WEBDRIVERIO_GETBOTMESSAGE hook there is no code sample available, as there hasnt been a real use case for it.

I’m only using GETBOTMESSAGE hook because of 2 reasons:

  1. Sometimes my bot has a dynamic delays between responses which results in error (BOT not responding error)
  2. There are few dynamic responses like “Typing…” , “Almost there!” and “Please Wait” from bot that I wanted to filter out.

GETBOTMESSAGE is the only way I found to do this kind of preprocessing.

If I handle the timeout error from WAITFORBOTTIMEOUT flag, I’m still facing a challenge with second point.

I will prepare a sample code for this use case

1 Like

So I added sample code to the Github repository, in the most simple form it looks like this:

module.exports = async (container, browser, element, html) => {
  const botMsg = { sender: 'bot', sourceData: { html } }
  botMsg.messageText = await element.getText()
  console.log('getbotmessage got text: ' + botMsg.messageText)
  return container.BotSays(botMsg)
}
1 Like

I’m able to use this code with a array compare logic to filter out response.
I’ll try pass buttons, cards and media as well (if that’s possible)

Thank you so much @Florian :blush:

1 Like