1

I'm writing a test to check our ratequote form on https://militaryvaloan.com/va-rates, I've been mostly successful getting it to work however I'm having trouble keeping the event listeners in order. Each step has some transition before the next steps are visible, so I am using driver.wait to make sure I can click or add text etc.

The problem comes when a step has input fields and a next button like 'Address and Zipcode', I've been unable to get the input fields filled out before the button gets clicked, so sometimes it tries clicking the next button before the fields are finished.

I've tried adding driver.sleep around each step to try and solve this but it still wants to click before the fields are done.

If someone could explain how to improve my code that would be greatly appreciated.

var webdriver = require('selenium-webdriver'),
    By = webdriver.By,
    until = webdriver.until;

var driver = new webdriver.Builder()
    .forBrowser('chrome')
    .build();

var _wait_and_input = function(element_type, descriptor, keys, message) {
  let element = element_type(descriptor);
  driver.wait(until.elementLocated(element)).then(() => {
    driver.wait(until.elementIsVisible(driver.findElement(element)), 20000).then((el) => {
      driver.sleep(1000).then(() => {
        if (message) console.log(message);
        el.sendKeys(keys);
      });
    })
  });
}

var _wait_and_click = function(element_type, descriptor, message) {
  let element = element_type(descriptor);
  driver.wait(until.elementLocated(element)).then(() => {
    driver.wait(until.elementIsVisible(driver.findElement(element)), 20000).then((el) => {
      driver.sleep(1000).then(() => {
        if (message) console.log(message);
        el.click();
      });
    })
  });
}

driver.get('https://militaryvaloan.com/va-rates').then(() => {

  _wait_and_click(By.id, 'va-streamline-btn', 'Loan Type');
  _wait_and_click(By.id, 'single-family-btn', 'Property Type');
  _wait_and_click(By.id, 'prime-res-btn', 'Property Use');

  _wait_and_input(By.name, 'state', 'w' + webdriver.Key.ENTER, 'State');
  _wait_and_click(By.id, 'next-state');

  _wait_and_click(By.id, 'next-mortgage-balance', 'Mortgage Balance');
  _wait_and_click(By.id, 'next-home-value', 'Home Value');
  _wait_and_click(By.id, 'next-interest-rate', 'Rate');
  _wait_and_click(By.id, 'credit-excellent', 'Credit');

  _wait_and_input(By.name, 'address', '123 Street SW', 'Address and Zipcode');
  _wait_and_input(By.name, 'zipcode', '98004');
  _wait_and_click(By.id, 'next-address-zip');

  _wait_and_input(By.name, 'firstname', 'Selenium', 'Name and Email');
  _wait_and_input(By.name, 'lastname', 'Selenium');
  _wait_and_input(By.name, 'email', 'null@fullbeaker.com');
  _wait_and_click(By.id, 'next-name-email');

  _wait_and_input(By.name, 'phone', '425-275-1238', 'Phone Number');
  _wait_and_click(By.id, 'next-phone');

  //driver.quit();

});

enter image description here

  • If it was me, I would set a breakpoint early in the test and walk it through the following lines. If you are able to complete the test while doing the steps, could be a timing issue. Should post the console after the execution on your question, helps us so we know if it's making it all the way through the test - Also seems like not all of the code is being shown. – DEnumber50 Oct 11 '18 at 19:16
  • @DEnumber50, the whole code is there it's just overflowed. – Andy H Oct 12 '18 at 18:33
0

Found the answer myself, I was only using wait's and no sleeps. I didn't know the selenium test would run asynchronously, which was why it was not staying in order.

My solution was to add a pause number and counter so I could force each step to run after each other:

let STEP_PAUSE = 500;
let STEP_COUNTER = 1;

function _wait_and_input(element_type, descriptor, keys) {
  driver.sleep(STEP_PAUSE * STEP_COUNTER++).then(() => {
    let element = element_type(descriptor);
    driver.findElement(element).then((input) => {
      input.sendKeys(keys);
    })
  })
}

function _wait_and_click(element_type, descriptor, message) {
  driver.sleep(STEP_PAUSE * STEP_COUNTER++).then(() => {
    let element = element_type(descriptor);
    driver.findElement(element).then((button) => {
      if (message) console.log('Pass: ' + message);
      button.click();
    })
  })
}

Ex:
First step runs after 500ms
Second step runs after 1000ms
Third step runs after 1500ms

and so on...

  • That sounds like a workaround rather than a solution the designers of the tools might have intended. Not that workarounds are bad though. In any case - Please mark this answer as accepted, so that others know there is an answer here that satisfied the original asker of the question (you). Thanks! – Carolus Oct 15 at 10:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.