0

I'm new to Selenium so I'm not sure if this is the best way to approach the problem, but I'm looking for a way to use xpath (or css) to locate a series of input elements and somehow iterate over all of them and input some text into them.

Something like the following:

<form>
  value1 <input type="text" placeholder="value1"><br>
  value2 <input type="text" placeholder="value2"><br>
  value3 <input type="text" placeholder="value3"><br>
</form>

I am able to locate the elements using this:

var input = driver.findElement(By.xpath("//input[@type='text']"))

I can input the first occurrence of the element found by xpath with the following:

input.sendKeys('Some text')

That's where I get stuck. I'm not sure how to enter values into the input fields after the first.

Ultimately, what I'd like to do is somehow send the text to all of the input fields located by the xpath filter. I was thinking it might be possible with a for loop but I'm not sure how to do it with the promise manager that webdriverjs uses.

Is this possible or is there a better way to do this?

jmreicha
  • 3,155
  • 7
  • 32
  • 39
  • There would be a findElements method the plural of what you are using. This will return a list which you can iterate and input the values.The singular findelement will always return the first matching element it finds in the page. – Grasshopper Oct 19 '16 at 17:37
  • Thanks, that gets me further along. Still trying to figure out how to iterate over the elements. – jmreicha Oct 19 '16 at 17:58
  • Have a look at this answer http://stackoverflow.com/questions/18677516/finding-multiple-elements – Grasshopper Oct 19 '16 at 18:07
  • @Grasshopper thanks, that post helped get me pointed in the right direction. – jmreicha Oct 19 '16 at 21:06

3 Answers3

1

You can do the following

driver.findElements(By.xpath("<xpath>")).then(function(elem) {
    for(var i=0; i<elem.length; i++){
        driver.findElements(By.xpath("<xpath>")).get(i).sendKeys('some Text');
    }
});

Just replace with the xpath of the elements that you are sending text too. Usually you can use .get() to choose a specific element from a list of elements returned from .findElements()

pretzo246
  • 125
  • 9
  • Thanks for the response. I'm looking to send the text to all of the elements instead of a specific index. Is there an easy way to do that? – jmreicha Oct 19 '16 at 17:57
  • You can iterate over all the elements returned from findElements() and then send it, but there is no way to send it all at once. You will have to use some form of iteration. :( – pretzo246 Oct 19 '16 at 17:59
  • Good to know. I don't mind sending them separately so I'll try to figure out how to iterate over all the elements, I'm not sure how to do that. – jmreicha Oct 19 '16 at 18:03
  • It's not working for me, I'm probably doing something wrong. I'm going to keep looking at it. – jmreicha Oct 19 '16 at 18:25
  • I keep getting `TypeError: driver.findElements(...).get is not a function`. – jmreicha Oct 19 '16 at 18:37
1

You should try using forEach when the same action has to be taken for all elements having common selector as below :-

driver.findElements(By.css("input[type='text']")).then(function(elements) {
  elements.forEach(function (input) {
      input.sendKeys('Some text');
  })
});

Or if you want to do same using promise, you'll need a reference to Selenium's promise for that as below :-

var promise = require('selenium-webdriver').promise;
var elements = driver.findElements(By.css("input[type='text']"))
promise.all(elements).then(function (input) {
     input.sendKeys('Some text');
});
Saurabh Gaur
  • 23,507
  • 10
  • 54
  • 73
  • `.each` seems like the cleanest approach but I am getting `TypeError: elements.each is not a function`, not sure why. – jmreicha Oct 19 '16 at 18:51
  • @jmreicha Sorry it should be `forEach`. Try with updated answer and let me know.. – Saurabh Gaur Oct 19 '16 at 19:04
  • I thought so too but for some reason it's still not working :/ Getting `TypeError: elements.forEach is not a function`. – jmreicha Oct 19 '16 at 19:08
  • 1
    Your answer set me on the right path, I had to wrap elements in a promise and then I was able to use the forEach loop. – jmreicha Oct 19 '16 at 21:05
0

I figured it out with help from others in this post. Here is what the working code looks like:

driver.findElements(By.css("input[type='text']"))
.then(function (inputs) {
    inputs.forEach(function (input) {
        input.sendKeys(password)
    })
})
jmreicha
  • 3,155
  • 7
  • 32
  • 39