Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document how to test with selenium #603

Closed
ben-manes opened this issue Nov 18, 2015 · 23 comments
Closed

Document how to test with selenium #603

ben-manes opened this issue Nov 18, 2015 · 23 comments

Comments

@ben-manes
Copy link

I'm having difficulty selecting an entry using webdriver. I can get as far as clicking on the input, but despite hacks have not yet been able to set the selection. A short guide on how to test this component would be appreciated.

@ben-manes
Copy link
Author

A hack, but this seems to work.

self.driver.find_element_by_class_name('Select-control').click()
wait = WebDriverWait(self.driver, timeout=10)
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'Select-option')))
options = self.driver.find_elements_by_class_name('Select-option')
for option in options:
    if option.text == value:
        option.click()
        break

@radar
Copy link

radar commented Nov 26, 2015

I have some Ruby code for this:

    first("#{element} .Select-input input").set(value)
    first("#{element} .Select-option").click

Setting the input's value will populate the component with the options that match that name. Then it's just a matter of clicking on that first option.

@mipearson
Copy link

Here's what we settled on for poltergeist/phantomJS. The trick is the keypresses need to be "sent" for it to work - can't just "set" the value of the hidden field.

    within(select_container_element) do
      find(".Select").click
      find(".Select").native.send_key(desired_option)
      find(".Select-option", text: desired_option).click
    end

@DanielSundberg
Copy link

In C#/Seleno I had to do the following to get it to work:

public void SetSelectText(string optionText) {
    var select = Find.Element(By.CssSelector(".Select"));
    select.Click();
    var options = Find.Elements(By.CssSelector(".Select-option")).ToList();
    options.ToList().Single(o => o.Text == optionText).Click();
}

That is with react-select@0.8.2, didn't bother with trying to get any later version to work.

At least some response whether this is prioritized or not would be nice.

@etburke
Copy link
Contributor

etburke commented Jan 20, 2016

I can't seem to get anything working with NightwatchJS.

@oren
Copy link

oren commented May 2, 2016

The following works for me:

In the IDE:

Command: sendKeys
Target: css=div.Select-control input
Value: Allergies${KEY_ENTER}

And the Java translation:

driver.findElement(By.cssSelector("div.Select-control input")).sendKeys("Allergies" + Keys.ENTER);

https://groups.google.com/forum/#!topic/selenium-users/FWsu_r7bbr0

@ghost
Copy link

ghost commented Nov 4, 2016

Hey,

I faced the same issue, here is my solution for the Nightwatch by creating a custom command.

The DOM I am manipulating in the script might have to be updated.

const util = require('util');
const events = require('events');

function selectOption() {
  events.EventEmitter.call(this);
}

util.inherits(selectOption, events.EventEmitter);

/**
 * Click an option in a select
 * It injects a script which triggers the events expected by the listeners in the core component.
 * @param {String} itemSelector The selector of the section where the select is.
 * @param {String} selectSelector Optional, the selector of the select. Default value: '.dropdow__element'.
 */
selectOption.prototype.command = function command(itemSelector, selectSelector = '.dropdown__element', callback) {
  this.api.execute((itemSel, selectSel) => {
    // eslint-disable no-undef
    var item = document.querySelector(itemSel); // eslint-disable-line no-var
    var select = item.parentNode.querySelector(selectSel); // eslint-disable-line no-var
    var evt = document.createEvent('MouseEvents'); // eslint-disable-line no-var
    evt.initEvent('mousedown', true, true);

    select.children[0].click();

    item.parentNode.getElementsByTagName('li')[1].children[0].dispatchEvent(evt);
    // eslint-enable no-undef
  }, [itemSelector, selectSelector], () => {
    if (typeof callback === 'function') {
      callback.call(this);
    }
    this.emit('complete');
  });

  return this;
};

module.exports = selectOption;

In fact the select is activated on the MouseDown event, here we trigger the event by injecting some code when testing the website.

@etburke I hope it can help you, let me know if it does what you are expecting.

@mfpiccolo
Copy link

For those of you trying to work with nightwatch and multiselect, I was able to get this to work with multi select using:

      .click('.custom-class')
      .click('.custom-class .Select-option[id*="-option-1"]')

@kgunbin
Copy link

kgunbin commented Jan 3, 2017

I've came up with a custom command for NightwatchJS which worked for me:
commands/setReactSelect.js

exports.command = function(selector, data) {
  var select = selector + ' .Select .Select-control';
  var item = selector + ' .Select .Select-menu .Select-option';
  var self = this;

  return this
    .waitForElementVisible(select, 1000)
    .click(select)
    .waitForElementVisible(item, 1000, function() {
      self.executeAsync(
        function() {
          var item = arguments[0][0];
          var data = arguments[0][1];
          var parent = arguments[0][2];

          var multi = Array.isArray(data);

          if(!multi) {
            data = [data];
          } else {
            // Close the dropdown after a second when all events are hopefully dispatched
            setTimeout(() => document.querySelector(parent + ' .Select-input input').blur(), 1000);
          }

          data.forEach((label) => {
            var option = Array.prototype.find.call(
              document.querySelectorAll(item),
              (e) => label == e.innerHTML
            );

            option.dispatchEvent(new MouseEvent('mousedown', {bubbles: true}));
          });
        },
        [[item, data, select]] // Pack params into an array, as Selenium works correct with a single parameter only
      );
    }).waitForElementNotPresent(item, 4000);
};

and the respective test

module.exports = {
  'Select Tasmania': function(browser) {
    var states = '#example .section';
    browser
      .url('https://jedwatson.github.io/react-select/')
      .setReactSelect(states, 'Tasmania')
      .waitForElementVisible('div.Select-value.State-Tas',  5000)
      .end();
  },

  'Select Chocolate and Peppermint': function(browser) {
    var root = '#example .section:nth-child(2)';

    browser
      .url('https://jedwatson.github.io/react-select/')
      .setReactSelect(root, ['Peppermint', 'Chocolate'])
      .waitForElementPresent(root + ' span.Select-value-icon', 5000) // Just assume any value is there
      .end();
  }
}

Hope this helps someone.

@joechromo
Copy link

This one worked for me:

.click('.Select-value-label') .click('.Select-option[id*="-option-1"]')

@RamadhanaRey
Copy link

Hi @oren how to handle next field with your selenium IDE command?
i have problem with next field, because the target always input on a first field..

@gor181
Copy link

gor181 commented Apr 13, 2017

What @radar proposed also works nicely in nightwatch alike syntax:

const commands = {
  fillSignUpInformation(email) {
    return this
      .setValue('@email', email || chance.email())
      .setValue('@password', 'somepw')
      .setValue('@companyName', 'company')
      .setValue('@phoneNumber', '+11234567890')
      .setValue('.Select-input input', 'United States')
      .click('.Select-option');
  },
  register() {
    return this.click('@submit');
  },
};

@PashminaT
Copy link

Has anyone got an example for selenium webdriver in java please?

@roscianfrank
Copy link

roscianfrank commented Jul 5, 2018

@PashminaT
Java version

driver.findElement(By.className("Select-control")).click();
WebDriverWait wait = new WebDriverWait(driver,10);
wait.until(ExpectedConditions.elementToBeClickable((By.className("Select-option"))));
List<WebElement> options = driver.findElements(By.className("Select-option"));
for(WebElement option: options){
if (option.getText().equalsIgnoreCase(DropDownValue)){
option.click();
break;
}
}

@Olliebaba
Copy link

@Roscian1Frank - your example worked for my team. Thanks!

@rocastaneda
Copy link

Command: sendKeys
Target: css=div.Select-control input
Value: 1
+
Command: click
Target: id=react-select-2--option-0

This works for me

@pietrofxq
Copy link

@Roscian1Frank could you make it work with latest versions? I cannot find a way to trigger click in the select and open the dropdown with webdriver

@roscianfrank
Copy link

Hi @pietrofxq,

My above example is still working for me on Selenium V3.14.0.
Need more details for investigation.
Thanks
Roscian

@Vyshnavi-N
Copy link

what does (clientName) in the code signify?

if (option.getText().equalsIgnoreCase(clientName)){

@roscianfrank
Copy link

roscianfrank commented Oct 31, 2018

@Vyshnavi-N
ClientName = Dropdown value
Value which you want to select from from drop-down

@kfox112
Copy link

kfox112 commented Oct 17, 2019

For anyone using nightwatch and the chrome driver, this is what worked for me (custom command):

exports.command = function(selector, data) {

    // Turn any numbers into a string
    keysToSend = "" + data;

    // Split the string on each character into an array of keys
    keysToSend = keysToSend.split("");

    // Hit enter after characters are typed
    keysToSend.push("\n");

    return this
        .waitForElementVisible(selector, 1000)
        .click(selector)
        .keys(keysToSend);
};

@jossmac
Copy link
Collaborator

jossmac commented Mar 17, 2020

Please reserve the GitHub issue tracker for bugs and feature requests. StackOverflow would be more appropriate for this sort of discussion.

@jossmac jossmac closed this as completed Mar 17, 2020
@DanielSundberg
Copy link

DanielSundberg commented Mar 17, 2020

Why close? This was reported as a documentation bug. Stackoverflow is not really the place for documentation of a custom component. The OP + many others including me wanted the creator of the component to document how it could be tested since automated testing is a first class citizen since many years.

Perhaps testing the component also could be made a bit easier. Take a look at the java example above...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests