vue-multiselect icon indicating copy to clipboard operation
vue-multiselect copied to clipboard

Can't interact via selenium

Open ianwremmel opened this issue 6 years ago • 11 comments

I'm attempting to write a selenium test that involves submitting a form that includes a vue-multiselect and I can't find any thing for selenium to click on that opens the options list.

Similarly, I can't find any JavaScript to run from dev tools that would open the options at https://vue-multiselect.js.org/. For example, I would expect something like document.querySelector('.multiselect').click() to open the options list.

Reproduction Link

https://vue-multiselect.js.org/

Steps to reproduce

  1. Visit https://vue-multiselect.js.org/
  2. Open dev tools
  3. Highlight various DOM nodes related to the main vue-multiselect on the page and run $0.click()
  4. Note that the options never appear

Expected behaviour

There should be some DOM node that receives a JavaScript or Selenium click event that causes the options list to appear

Actual behaviour

The options list does not appear.

ianwremmel avatar Feb 13 '19 01:02 ianwremmel

Also seeing this issue. Something broke this behavior in one of the latest versions, as I was definitely able to open the dropdown via click in a Selenium test w/ v2.0.8.

rnicholus avatar Feb 20 '19 21:02 rnicholus

Good to know that it did work as one would expect. I did get my tests working with selenium's click, but not dev tools. It seems to have something to do with whether the document has focus; IIRC, i could get the dev tools top open the dropdown with setTimeout(() => $0.click(), 3000) if i clicked into the document first.

ianwremmel avatar Feb 20 '19 22:02 ianwremmel

i ended up reverting to v2.0.8 as I ran into a number of other regressions and breaking changes w/ the library

rnicholus avatar Feb 20 '19 22:02 rnicholus

Hey! Would you be able to identify what exactly has caused this regression? I also wonder if this also happens on the v3 branch. Though in 3.0 the multiselect requires more than just focus to properly activate.

shentao avatar Feb 24 '19 21:02 shentao

I looked for a short time, and wasn't able to immediately determine what was causing this. I ran out of time and had to revert. Sorry I couldn't be more helpful 😞

rnicholus avatar Feb 25 '19 14:02 rnicholus

I have the same issue, too, using version 2.1.6. Unable to open the multiselect or click to any of their elements; the error given is "element not interactable". If I try to wait for simply element to be visible, it goes in timeout.

tiec7 avatar Mar 25 '21 08:03 tiec7

Same issue. Made a stupid workaround where I defined some accessor functions in the window namespace in mounted and destroyed. No clicking: I just use the reactive stuff and set variables. I don't need to test the select component itself.

It does present a challenge still since it behaves completely differently than an actual select.

velis74 avatar Aug 11 '21 05:08 velis74

Is selenium somehow behind in how you can interact with the DOM compared to say Cypress? I haven’t had any issues with interacting with the component using the latter. What really helps is creating a Page Object that simplifies the interactions and using that instead.

shentao avatar Aug 11 '21 09:08 shentao

Cypress is entirely JavaScript and doesn't use any automation built into the browser while selenium only uses automation built into the browser. I don't know that "behind" is the right word, they're just fundamentally different.

I haven't used vue-multiselect for a few years (partly because of this, but mostly because various organization changes have me writing react these days), but I'm not sure how a PageObject would help here. The problem, at least when I used the library, was not around code organization, but was instead around an inability to find any event target that would cause the options to appear.

Are you saying Cypress can interact with a vue-multiselect input?

ianwremmel avatar Aug 11 '21 14:08 ianwremmel

I gave up months ago switching to cypress. more reliable, more handy, faster.

tiec7 avatar Aug 11 '21 14:08 tiec7

Sadly I’m not an expert on Selenium (it’s been years since I last touched it and back then I was hardly proficient with e2e tests). Generally, with Cypress it works pretty decently, especially once you abstract the interactions into a PageObject. In one of my projects we use it like this:

new MultipleSelect({ label: 'Select User' })
          .toggle()
          .shouldHaveOptions([
            'John Doe',
            'Jane Doe',
          ])
          .select('John Doe')

The page object is implemented like this:

class MultipleSelect extends FormElement {
  getSearchInput () {
    return this.getElement().find('.multiselect__input')
  }

  getValue () {
    return this.getElement().find('.multiselect__single')
  }

  getTrigger () {
    return this.getElement().find('.multiselect__select')
  }

  getOptions () {
    return this.getElement().find('.multiselect__content')
  }

  toggle () {
    this.getTrigger().click({ force: true })
    return this
  }

  select (label) {
    this.getOptions()
      .contains(label, { timeout: 15000 })
      .click({ force: true })
    return this
  }
  
  shouldHaveOptions (options) {
    this.getOptions().within(() => {
      cy.get('.multiselect__element').should('have.length', options.length)

      options.forEach(option => {
        cy.findByText(option).should('exist')
      })
    })
    return this
  }
  
  // more helper functions here

And it really works pretty smoothly. Though I agree that without a page object, memorizing all the CSS classes to access the contents is frustrating, to say the least.

Not sure if this will be helpful in any way for Selenium users though...

shentao avatar Aug 11 '21 18:08 shentao