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

Locating drop down menu without unique identifier inside a div with an id #29

Open
ialtero opened this issue Nov 17, 2020 · 17 comments
Open

Comments

@ialtero
Copy link

ialtero commented Nov 17, 2020

Need to see if there is a way to locate drop down menu choices within a div in able to select drop down choices, which do not have unique identifiers. In this case, div has an id which I can use to locate it, but the view box vega embed graph drop down menu does not have a unique identifier. See below:


<div class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-4" id="pa_graph_1">
<div class="vega-embed has-actions"><div class="chart-wrapper" role="graphics-document" aria-roledescription="visualization" aria-label="Vega visualization" style="cursor: default;"><canvas width="262" height="269" class="marks" style="width: 252px; height: 259px;"></canvas><form class="vega-bindings"></form></div><details title="Click to view actions">
<summary>
<svg viewBox="0 0 16 16" fill="currentColor" stroke="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
  <circle r="2" cy="8" cx="2"></circle>
  <circle r="2" cy="8" cx="8"></circle>
  <circle r="2" cy="8" cx="14"></circle>
</svg></summary>
<div class="vega-actions">
<a href="#" target="_blank" download="visualization.svg">Save as SVG</a>
<a href="#" target="_blank" download="visualization.png">Save as PNG</a>
<a href="#">View Source</a>
<a href="#">View Compiled Vega</a>
<a href="#">Open in Vega Editor</a>
</div></details></div></div>

<div class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-4" id="pa_graph_2">
<div class="vega-embed has-actions"><div class="chart-wrapper" role="graphics-document" aria-roledescription="visualization" aria-label="Vega visualization" style="cursor: default;"><canvas width="265" height="290" class="marks" style="width: 255px; height: 279px;"></canvas><form class="vega-bindings"></form></div><details title="Click to view actions">
<summary>
<svg viewBox="0 0 16 16" fill="currentColor" stroke="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
  <circle r="2" cy="8" cx="2"></circle>
  <circle r="2" cy="8" cx="8"></circle>
  <circle r="2" cy="8" cx="14"></circle>
</svg></summary>
<div class="vega-actions">
<a href="#" target="_blank" download="visualization.svg">Save as SVG</a>
<a href="#" target="_blank" download="visualization.png">Save as PNG</a>
<a href="#">View Source</a>
<a href="#">View Compiled Vega</a>
<a href="#">Open in Vega Editor</a>
</div></details></div></div>

@titusfortner
Copy link
Member

Watir (& Nerodia) support many different ways to locate elements (http://watir.com/guides/locating/)

I'm not familiar with this type of drop down, though, what do you need to identify by and what do you need to click?

@ialtero
Copy link
Author

ialtero commented Nov 17, 2020

I need to click on

<a href="#">View Compiled Vega</a>

"in each div. (id=" id="pa_graph_1" and id="pa_graph_2")

@titusfortner
Copy link
Member

titusfortner commented Nov 17, 2020

So in Ruby it would look like:
browser.div(id: 'pa_graph_1').a(text: 'View Compiled Vega').click
you'd have to translate the equivalent in Python for Nerodia...

@ialtero
Copy link
Author

ialtero commented Nov 17, 2020

I've tried:

browser.div(id = 'pa_graph_1').a(text='View Compiled Vega').click()
browser.div(id = 'pa_graph_1').link(text='View Compiled Vega').click()

Any other ideas?

@titusfortner
Copy link
Member

are you getting an error, or is it not doing anything?

@ialtero
Copy link
Author

ialtero commented Nov 17, 2020

browser.div(id = 'pa_graph_1').a(text='View Compiled Vega').click()
Error: AttributeError: Element 'Div' has no attribute 'a'

So I tried:

browser.div(id = 'pa_graph_1').link(text='View Compiled Vega').click()
Error: nerodia.exception.UnknownObjectException: element located, but timed out after 30 seconds, waiting for #<Anchor: located: True; {'id': 'pa_graph_1', 'tag_name': 'div'} --> {'text': 'View Compiled Vega', 'tag_name': 'a'}> to be present

@titusfortner
Copy link
Member

Right, so this means that it is in the DOM, but that Selenium has calculated that it is not visible to the end user.
Is there something you need to click or hover over in order to make it visible?

@ialtero
Copy link
Author

ialtero commented Nov 18, 2020

These href 'View Compiled Vega' choice is part of a drop down list under svg:

 <svg viewBox="0 0 16 16" fill="currentColor" stroke="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
  <circle r="2" cy="8" cx="2"></circle>
  <circle r="2" cy="8" cx="8"></circle>
  <circle r="2" cy="8" cx="14"></circle>
</svg>

However, I don't have a 'name' or 'id' for svg, which I can potentially use to click on it. However, this svg drop box is part of the overall div, which does have an 'id'

Here is an example of the Vega embed dropdown menu (https://observablehq.com/@vega/hello-vega-embed), which is similar to what I am using without an overall div id.

I am trying to do as follows:

  1. click on the drop down menu for this vega embed graph drop down menu,
  2. click on 'View Compiled Vega'
  3. change focus to new window
  4. acquire json data on new window
  5. close new vega json window, and go back to original window.

@titusfortner
Copy link
Member

I have good news and bad news.
First, this is hidden inside an iframe, which is causing a problem.

Good news: This (Ruby) code works!

irb(main):220:0> browser = Watir::Browser.new :firefox
=> #<Watir::Browser:0x7eeaa404f092b38e url="about:blank" title="">
irb(main):221:0> browser.goto 'https://observablehq.com/@vega/hello-vega-embed'
=> "https://observablehq.com/@vega/hello-vega-embed"
irb(main):222:0> browser.iframe.div(class: 'vega-embed-wrapper').svg.click
=> nil
irb(main):223:0> browser.iframe.link(text: 'View Compiled Vega').click
=> nil
irb(main):224:0> browser.windows.last.use
=> #<Watir::Window:0x..fda6a7121231443ac located=true>
irb(main):227:0> JSON.parse browser.code.text
=> {"$schema"=>"https://vega.github.io/schema/vega/v5.json", "background"=>"white", "padding"=>5, "width"=>360, "height"=>200, "style"=>"cell", "data"=>[{"name"=>"a_store"}, {"name"=>"source", "values"=>[{"a"=>"A", "b"=>28}, {"a"=>"B", "b"=>55}, {"a"=>"C", "b"=>43}, {"a"=>"D", "b"=>91}, {"a"=>"E", "b"=>81}, {"a"=>"F", "b"=>53}, {"a"=>"G", "b"=>19}, {"a"=>"H", "b"=>87}, {"a"=>"I", "b"=>52}]}, {"name"=>"data_0", "source"=>"source", "transform"=>[{"type"=>"identifier", "as"=>"_vgsid_"}, {"type"=>"filter", "expr"=>"isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"}]}], "signals"=>[{"name"=>"unit", "value"=>{}, "on"=>[{"events"=>"mousemove", "update"=>"isTuple(group()) ? group() : unit"}]}, {"name"=>"a", "update"=>"vlSelectionResolve(\"a_store\", \"union\")"}, {"name"=>"a_tuple", "on"=>[{"events"=>[{"source"=>"scope", "type"=>"click"}], "update"=>"datum && item().mark.marktype !== 'group' ? {unit: \"\", fields: a_tuple_fields, values: [(item().isVoronoi ? datum.datum : datum)[\"_vgsid_\"]]} : null", "force"=>true}, {"events"=>[{"source"=>"scope", "type"=>"dblclick"}], "update"=>"null"}]}, {"name"=>"a_tuple_fields", "value"=>[{"type"=>"E", "field"=>"_vgsid_"}]}, {"name"=>"a_modify", "on"=>[{"events"=>{"signal"=>"a_tuple"}, "update"=>"modify(\"a_store\", a_tuple, true)"}]}], "marks"=>[{"name"=>"marks", "type"=>"rect", "style"=>["bar"], "interactive"=>true, "from"=>{"data"=>"data_0"}, "encode"=>{"update"=>{"fill"=>[{"test"=>"!(length(data(\"a_store\"))) || (vlSelectionTest(\"a_store\", datum))", "value"=>"steelblue"}, {"value"=>"grey"}], "tooltip"=>{"signal"=>"format(datum[\"b\"], \"\")"}, "ariaRoleDescription"=>{"value"=>"bar"}, "description"=>{"signal"=>"\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"}, "x"=>{"scale"=>"x", "field"=>"a"}, "width"=>{"scale"=>"x", "band"=>1}, "y"=>{"scale"=>"y", "field"=>"b"}, "y2"=>{"scale"=>"y", "value"=>0}}}}], "scales"=>[{"name"=>"x", "type"=>"band", "domain"=>{"data"=>"data_0", "field"=>"a", "sort"=>true}, "range"=>[0, {"signal"=>"width"}], "paddingInner"=>0.1, "paddingOuter"=>0.05}, {"name"=>"y", "type"=>"linear", "domain"=>{"data"=>"data_0", "field"=>"b"}, "range"=>[{"signal"=>"height"}, 0], "nice"=>true, "zero"=>true}], "axes"=>[{"scale"=>"y", "orient"=>"left", "gridScale"=>"x", "grid"=>true, "tickCount"=>{"signal"=>"ceil(height/40)"}, "domain"=>false, "labels"=>false, "aria"=>false, "maxExtent"=>0, "minExtent"=>0, "ticks"=>false, "zindex"=>0}, {"scale"=>"x", "orient"=>"bottom", "grid"=>false, "title"=>"a", "labelAlign"=>"right", "labelAngle"=>270, "labelBaseline"=>"middle", "zindex"=>0}, {"scale"=>"y", "orient"=>"left", "grid"=>false, "title"=>"b", "labelOverlap"=>true, "tickCount"=>{"signal"=>"ceil(height/40)"}, "zindex"=>0}]}
irb(main):228:0> 

Bad news: it doesn't work with Chrome for some reason. Some kind of bug trying to interact with elements on the second window, the driver just hangs...

@ialtero
Copy link
Author

ialtero commented Nov 22, 2020

It seems I get a bit further in chrome than firefox.

I tried the following in chrome, and this works:

    div_a = self.browser.iframe().div(class_name = "vega-embed-wrapper")
    div_a.scroll_into_view()
    div_a.svg().click()
    self.browser.iframe().link(text = 'View Compiled Vega').click()
    # Print JSON data from 'Vega JSON Source' window
    print(self.browser.text)
    # Go back to original window
    self.browser.window(title = 'Hello Vega-Embed / Vega / Observable').use()
    # Print original browser text
    print(self.browser.text)
    self.browser.window(title = 'Vega JSON Source').use()

However, after ' self.browser.window(title = 'Vega JSON Source').use()', everything hangs as you mentioned.

The following doesn't work either in chrome:

   self.browser.window(title = 'Vega JSON Source').close()

In regards to Firefox browser, I get an error just by trying:

   self.browser.window(title = 'Hello Vega-Embed / Vega / Observable').use()

Error:

  File "/home/imaltero/.local/lib/python3.6/site-packages/nerodia/window.py", line 284, in _matches
    self.driver.switch_to.window(orig)
  File "/home/imaltero/.local/lib/python3.6/site-packages/selenium/webdriver/remote/switch_to.py", line 112, in window
    self._w3c_window(window_name)
  File "/home/imaltero/.local/lib/python3.6/site-packages/selenium/webdriver/remote/switch_to.py", line 123, in _w3c_window
    send_handle(window_name)
  File "/home/imaltero/.local/lib/python3.6/site-packages/selenium/webdriver/remote/switch_to.py", line 119, in send_handle
    self._driver.execute(Command.SWITCH_TO_WINDOW, {'handle': h})
  File "/home/imaltero/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/home/imaltero/.local/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidArgumentException: Message: Expected "handle" to be a string, got [object Undefined] undefined

@titusfortner
Copy link
Member

I think you're just referencing the window incorrectly somehow. In chrome and Firefox the windows appear in order, so you can use the last one in the array.

@ialtero
Copy link
Author

ialtero commented Nov 23, 2020

I did have 'self.browser.window(index=1).close()" work as expected closing Vega JSON Source page, but 'self.browser.window(index=1).use()' still hangs in chrome, where index=0 is original window and index=1 is Vega JSON Source page.

However using the same code for Chrome, I am still having issues with Firefox just by simply using 'self.browser.window(index=0).use()' or 'self.browser.window(title = 'Hello Vega-Embed / Vega / Observable').use()' for example as well as close() function, which work fine in Chrome but not Firefox getting same error as above.

@titusfortner
Copy link
Member

Oh weird, I can reproduce this bug in Ruby Watir. Some kind of infinite loop when trying to iterate over a window set with a single window by looking at title, I'll raise an issue on Watir. I'm thinking watir/watir#849 might address the issue, or at least make it easier to switch back to the original window, but not sure when that will get added.

In the meantime, this should work:

irb(main):025:0> browser.windows.last.use
=> #<Watir::Window:0x65022af5bb8f248c located=true>
irb(main):026:0> browser.window.close
=> #<Watir::Window:0x65022af5bb8f248c located=true>
irb(main):027:0> browser.windows.first.use
=> #<Watir::Window:0x10eb7bc745bf5a98 located=true>
irb(main):028:0> 

@ialtero
Copy link
Author

ialtero commented Nov 24, 2020

In regards to Chrome, I noticed that in order for me to interact and extract json data from the new Vega JSON Source page I need to be able to use the use() function to change focus to this new window I just opened. I see the issue may be related to how the new Vega JSON Source page itself (possibly url?).

If Instead of opening the Vega JSON Source option I open 'Open in Vega Editor' option page, I am able to change focus to this new Open in Vega Editor window using the use() function as expected. So I am wondering if there is a work around I could to interact with Vega JSON Source page given this new finding.

As far as Firefox browser, I still get an InvalidArgumentException Exception Error as mentioned above when trying to use 'browser.window(index=1).use()' or 'browser.window(title = 'Vega Editor').use()', which both functions work fine in Chrome browser.

@titusfortner
Copy link
Member

@ialtero are you using geckodriver v0.28?
@lmtierney any chance you can duplicate this in Firefox?
(there's an actual bug in here for the Title stuff, but index works in Ruby, so I'm not sure what is different in Python?)

@ialtero
Copy link
Author

ialtero commented Nov 24, 2020

I am currently using geckodriver v0.24, and firefox v83

@ialtero
Copy link
Author

ialtero commented Nov 24, 2020

Ok, I just tried it with v0.28 and it works now. The only issue now in both browser is to interact/change focus to Vega JSON Source option page instead of Open in Vega Editor option page.

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

2 participants