This is my first time writing automated test for React App. I use Ruby Selenium Webdriver. I'm trying to find this element <i aria-hidden="true" class="fa fa-cog">::before</i>
<thead>...</thead>
<tbody>
<tr id="coach56">...</tr>
<tr id="coach88">
<td>...</td>
<td class="text-right">
<i aria-hidden="true" class="fa fa-cog">::before</i>
</td>
</tr>
</tbody>
and click on it
table = #browser.find_element(:css, 'table.table')
rows = table.find_elements(:tag_name, 'tr')
cog = rows.last.find_elements(:tag_name, 'td').last.find_element(:tag_name, 'i')
Even though my webdriver could find the element just fine (when I do pp cog)
#<Selenium::WebDriver::Element:0x..fb0ec34323433b358 id="1a0b9a5e-a789-cf4c-9de2-d140d628bb43">
When I tried clicking on it cog.click I get this error
Selenium::WebDriver::Error::ElementNotInteractableError:
stack backtrace:
0: 0x106a3abc4 - backtrace::backtrace::trace::h6e3f5d4ff9dcd09c
1: 0x106a3af9f - backtrace::capture::Backtrace::new::he142908a5a8f9eda
2: 0x1066cb3ef - webdriver::error::WebDriverError::new::h11cfe73261fd6398
3: 0x1066d8932 - geckodriver::marionette::MarionetteSession::response::hf1e03dba1b51e3d2
4: 0x1066e7a9a - geckodriver::marionette::MarionetteConnection::send_command::h198264f6a411d523
5: 0x1066d7238 - _$LT$geckodriver..marionette..MarionetteHandler$u20$as$u20$webdriver..server..WebDriverHandler$LT$geckodriver..marionette..GeckoExtensionRoute$GT$$GT$::handle_command::h1ce60025abbb1e2f
6: 0x106660233 - _$LT$webdriver..server..Dispatcher$LT$T$C$$u20$U$GT$$GT$::run::h91f334bc53d085f2
7: 0x1066cc00a - webdriver::server::start::_$u7b$$u7b$closure$u7d$$u7d$::h2009c93c17caa760
8: 0x1065c3fda - std::sys_common::backtrace::__rust_begin_short_backtrace::h7e6fc63778e17700
9: 0x1065d51e3 - std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h9046a824429b7834
10: 0x106582faa - _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h7c96f21f7f4901f2
11: 0x1065d6029 - std::panicking::try::do_call::hd2ff6fc209e7ca99
12: 0x106d5caec - __rust_maybe_catch_panic
13: 0x1065d5bdc - std::panicking::try::h56209e5aa6d1fe14
14: 0x1065d2a05 - std::panic::catch_unwind::h9b8731248ee7a1e3
15: 0x1065d4f2e - std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::hf264dcc876d92ec3
16: 0x106642bf3 - _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h9197fed04f7f649b
17: 0x106d58d5b - std::sys::imp::thread::Thread::new::thread_start::h7c0954aeccca31ea
18: 0x7fff9d27b93a - _pthread_body
19: 0x7fff9d27b886 - _pthread_start
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/response.rb:71:in `assert_ok'
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/response.rb:34:in `initialize'
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/http/common.rb:83:in `new'
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/http/common.rb:83:in `create_response'
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/http/default.rb:106:in `request'
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/http/common.rb:61:in `call'
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/bridge.rb:170:in `execute'
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/w3c/bridge.rb:537:in `execute'
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/w3c/bridge.rb:360:in `click_element'
/Users/trea/.rvm/gems/ruby-2.4.0#trea/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/common/element.rb:74:in `click'
Any suggestion to resolve this? I have also tried to hover the element first then click it but also got the same error on clicking.
Thank you
Related
Code works in development environment. When deployed to Heroku, logs show error ActionView::Template::Error (undefined method...). This is on the show, edit action and seems to be related to the i18n format I am using.
I commented out the code on the view, redeployed app and confirmed it works on Heroku.
# config/locales/en.yml
en:
hello: "Hello world"
time:
formats:
short: '%H:%M'
View
<li>Players arrive: <span class="float-right"><%= l #schedule.start_time - 30.minutes, format: :short %> am</span></li>
<li>Coin Toss: <span class="float-right"><%= l #schedule.start_time - 20.minutes, format: :short %> am</span></li>
<li>Game Start: <span class="float-right"><%= #schedule.start_time.to_s(:time) %> am</span></li>
<li>Lunch Break: <span class="float-right"><%= l #schedule.start_time + 3.5.hours, format: :short %> pm</span></li>
<li>2nd Innings Start: <span class="float-right"><%= l #schedule.start_time + 4.hours, format: :short %> pm</span></li>
<li>Game End: <span class="float-right"><%= l #schedule.start_time + 7.25.hours, format: :short %> pm</span></li>
Heroku Logs
2019-04-23T16:43:39.473185+00:00 app[web.1]: D, [2019-04-23T16:43:39.473113 #8] DEBUG -- : [85be5233-b649-40a0-9707-eeaef1773522] [1m[36mSelection Load (6.5ms)[0m [1m[34mSELECT "selections".* FROM "selections" WHERE "selections"."schedule_id" = $1 AND "selections"."user_id" = $2 LIMIT $3[0m [["schedule_id", 1], ["user_id", 1], ["LIMIT", 1]]
2019-04-23T16:43:39.492684+00:00 app[web.1]: I, [2019-04-23T16:43:39.492587 #8] INFO -- : [85be5233-b649-40a0-9707-eeaef1773522] Rendering schedules/show.html.erb within layouts/application
2019-04-23T16:43:39.494351+00:00 app[web.1]: I, [2019-04-23T16:43:39.494284 #8] INFO -- : [85be5233-b649-40a0-9707-eeaef1773522] Rendered schedules/partials/_match_centre.html.erb (0.5ms)
2019-04-23T16:43:39.502847+00:00 app[web.1]: I, [2019-04-23T16:43:39.502777 #8] INFO -- : [85be5233-b649-40a0-9707-eeaef1773522] Rendered schedules/partials/_run_times.html.erb (8.0ms)
2019-04-23T16:43:39.502959+00:00 app[web.1]: I, [2019-04-23T16:43:39.502898 #8] INFO -- : [85be5233-b649-40a0-9707-eeaef1773522] Rendered schedules/show.html.erb within layouts/application (10.2ms)
2019-04-23T16:43:39.503140+00:00 app[web.1]: I, [2019-04-23T16:43:39.503080 #8] INFO -- : [85be5233-b649-40a0-9707-eeaef1773522] Completed 500 Internal Server Error in 51ms (ActiveRecord: 24.6ms)
2019-04-23T16:43:39.503731+00:00 app[web.1]: F, [2019-04-23T16:43:39.503670 #8] FATAL -- : [85be5233-b649-40a0-9707-eeaef1773522]
2019-04-23T16:43:39.503806+00:00 app[web.1]: F, [2019-04-23T16:43:39.503731 #8] FATAL -- : [85be5233-b649-40a0-9707-eeaef1773522] ActionView::Template::Error (undefined method `start_time' for #<Schedule:0x00007fbde401fb68>):
2019-04-23T16:43:39.503974+00:00 app[web.1]: F, [2019-04-23T16:43:39.503913 #8] FATAL -- : [85be5233-b649-40a0-9707-eeaef1773522] 2: <div class="card-body">
2019-04-23T16:43:39.503977+00:00 app[web.1]: [85be5233-b649-40a0-9707-eeaef1773522] 3: <h5 class="card-title"><strong>Match Run Times</strong></h5>
2019-04-23T16:43:39.503981+00:00 app[web.1]: [85be5233-b649-40a0-9707-eeaef1773522] 4: <ul class="card-text">
2019-04-23T16:43:39.503983+00:00 app[web.1]: [85be5233-b649-40a0-9707-eeaef1773522] 5: <li>Players arrive: <span class="float-right"><%= l #schedule.start_time - 30.minutes, format: :short %> am</span></li>
2019-04-23T16:43:39.503985+00:00 app[web.1]: [85be5233-b649-40a0-9707-eeaef1773522] 6: <li>Coin Toss: <span class="float-right"><%= l #schedule.start_time - 20.minutes, format: :short %> am</span></li>
2019-04-23T16:43:39.503987+00:00 app[web.1]: [85be5233-b649-40a0-9707-eeaef1773522] 7: <li>Game Start: <span class="float-right"><%= #schedule.start_time.to_s(:time) %> am</span></li>
2019-04-23T16:43:39.503989+00:00 app[web.1]: [85be5233-b649-40a0-9707-eeaef1773522] 8: <li>Lunch Break: <span class="float-right"><%= l #schedule.start_time + 3.5.hours, format: :short %> pm</span></li>
2019-04-23T16:43:39.504028+00:00 app[web.1]: F, [2019-04-23T16:43:39.503964 #8] FATAL -- : [85be5233-b649-40a0-9707-eeaef1773522]
2019-04-23T16:43:39.504098+00:00 app[web.1]: F, [2019-04-23T16:43:39.504039 #8] FATAL -- : [85be5233-b649-40a0-9707-eeaef1773522] app/views/schedules/partials/_run_times.html.erb:5:in `_app_views_schedules_partials__run_times_html_erb__4351229195490545164_70226775711600'
2019-04-23T16:43:39.504101+00:00 app[web.1]: [85be5233-b649-40a0-9707-eeaef1773522] app/views/schedules/show.html.erb:9:in `_app_views_schedules_show_html_erb__4220913006891638050_70226775641260'
I have this list of color variables:
//** Smoke
$smoke-hex-l-10: #504c51;
$smoke-hex-l-20: #575358;
$smoke-hex-l-25: #5b575c;
$smoke-hex-l-30: #5e5a60;
$smoke-hex-l-40: #656167;
$smoke-hex-l-50: #6d686e;
$smoke-hex-l-60: #746f76;
$smoke-hex-l-70: #7b767d;
$smoke-hex-l-75: #7f7981;
$smoke-hex-l-80: #827d84;
$smoke-hex-l-90: #89848b;
$smoke-hex-l-100: #908b92;
$smoke-hex-d-10: #423f43;
$smoke-hex-d-20: #3c3a3d;
$smoke-hex-d-25: #3a373b;
$smoke-hex-d-30: #383539;
$smoke-hex-d-40: #343135;
$smoke-hex-d-50: #302e31;
$smoke-hex-d-60: #2d2b2e;
$smoke-hex-d-70: #2b292b;
$smoke-hex-d-75: #29282a;
$smoke-hex-d-80: #282629;
$smoke-hex-d-90: #262427;
$smoke-hex-d-100: #242325
Is there a way to optimize this list in some way? I'm not very good a Sass, but I've read about Sass Maps, but I can't wrap my head around the concept.
Or if a list like that it's just the way to do it?
Thanks for your help.
Of course you can use sass maps to store these variables, it may look like this:
//** Smoke
$smoke-hex-l: (
10: #504c51,
20: #575358,
25: #5b575c,
30: #5e5a60,
40: #656167,
50: #6d686e,
60: #746f76,
70: #7b767d,
75: #7f7981,
80: #827d84,
90: #89848b,
100: #908b92,
);
$smoke-hex-d: (
10: #423f43,
20: #3c3a3d,
25: #3a373b,
30: #383539,
40: #343135,
50: #302e31,
60: #2d2b2e,
70: #2b292b,
75: #29282a,
80: #282629,
90: #262427,
100: #24232,
);
and can be accessed like: $smoke-color: map-get($smoke-hex-l, 10);
However it looks like these colors are just lighten / darken versions of common base color, something like #49464a. In this case you can simplify your code by using color manipulation functions that are available in Sass. In particular lighten() and darken() will be enough to replace whole set of colors that you have.
I have a HTML file code which is shown below:
<table id="plans" class="brand-table">
<thead>
<tr>
<th class="domain">Plans</th>
<th class="basic">Basic</th>
<th class="plus">Plus</th>
<th class="prime">Prime</th>
</tr>
</thead>
<tbody>
<tr class="even">
<td>
www.test.com
</td>
<td>
<input name="upgrade" type="radio">
//this span element is hidden
<span class="plan_status"></span>
</td>
<td>
<input name="upgrade" value="plus www.test.com" type="radio">
//this span element is hidden
<span class="plan_status"></span>
</td>
<td>
<input name="upgrade" value="prime www.test.com" checked="" type="radio">
<span class="plan_status">current</span>
</td>
</tr>
</tbody>
</table>
I want to check which plan is the current plan in the page through Ruby Watir. Below is the script:
require 'watir'
browser = Watir::Browser.new(:chrome)
browser.goto('file:///C:/Users/Ashwin/Desktop/new.html')
browser.table(:id, 'plans').tds.each do |table_row|
if table_row.input(:value, 'plus www.test.com').text =~ /current/i
p 'current plan status is plus'
elsif table_row.input(:value, 'prime www.test.com').text =~ /current/i
p 'current plan status is prime'
else
p 'current plan status is basic'
end
end
But I am getting the output as:
C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.6.11/lib/watir-webdriver/elements/element.rb:513:in `assert_exists': unable to locate element, using {:value=>"plus www.test.com", :tag_name=>"input"} (Watir::Exception::UnknownObjectException)
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.6.11/lib/watir-webdriver/elements/element.rb:86:in `text'
from C:/Users/Name/Documents/NetBeansProjects/RubyApplication6/lib/new_main15.rb:8:in `block in <main>'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.6.11/lib/watir-webdriver/element_collection.rb:29:in `each'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.6.11/lib/watir-webdriver/element_collection.rb:29:in `each'
from C:/Users/Name/Documents/NetBeansProjects/RubyApplication6/lib/new_main15.rb:7:in `<main>'
But I want the output to be as:
current plan status is prime
Can anyone please help?
Thanks in advance
Instead of checking which td element has the "current" text, I would suggest checking which radio has the checked attribute. This reduces the number of elements you have to worry about interacting with.
You can find the selected radio using:
table_row.radios.find(&:set?).value
You can then check the value of the radio to see if it starts with the word "plus" or "prime":
# Note that we scope to the tbody to ignore the header row.
# Also make sure you do `trs` not `tds` for the rows.
table_rows = browser.table(id: 'plans').tbody.trs
# Iterate through the rows and check the checked radio button
table_rows.each do |table_row|
case table_row.radios.find(&:set?).value
when /^plus/
p 'current plan status is plus'
when /^prime/
p 'current plan status is prime'
else
p 'current plan status is basic'
end
end
Note that for older versions of Ruby (ie v1.9), you will need to find the selected radio using:
table_row.radios.find { |r| r.set? }.value
I have a basic ruby program I've been using for several months now that retrieves hardware and virtualguest machine details for my account. Up until roughly 3 days ago this always ran fine and relatively fast. Since then it often crashes and/or the virtualguest retrieval takes 20-30 times longer than it has in the past. What could be the issue here? The crash stack is not very informative of the problem.
Program:
require 'rubygems'
require 'softlayer_api'
require 'pp'
client = SoftLayer::Client.new(:username => user, :api_key => api_key, :timeout => 999999)
account = client['Account'].object_mask("mask[virtualGuestCount,hardwareCount]").getObject()
virtual_machines_count = account["virtualGuestCount"]
bare_metal_machines_count = account["hardwareCount"]
bare_metal_machines_count_index = 0
virtual_machines_count_index = 0
for i in 0..(bare_metal_machines_count/10.0).ceil - 1
list_of_baremetal_machines = client['Account'].result_limit(i*10,10).object_mask("mask[id, hostname, fullyQualifiedDomainName, provisionDate, datacenter[name], billingItem[recurringFee, associatedChildren[recurringFee], orderItem[description, order[userRecord[username], id]]], operatingSystem[id, softwareLicense[id, softwareDescription[longDescription]]], tagReferences[tagId, tag[name]], primaryIpAddress, primaryBackendIpAddress]").getHardware
for x in 0..list_of_baremetal_machines.length - 1
bare_metal_machines_count_index = bare_metal_machines_count_index + 1
if bare_metal_machines_count_index == bare_metal_machines_count
pp("Finished retrieving " + bare_metal_machines_count.to_s + " bare metal machines")
end
end
end
for i in 0..(virtual_machines_count/10.0).ceil - 1
list_of_virtual_machines = client['Account'].result_limit(i*10,10).object_mask("mask[id, hostname, fullyQualifiedDomainName, provisionDate, datacenter[name], billingItem[recurringFee, associatedChildren[recurringFee], orderItem[description, order[userRecord[username], id]]], operatingSystem[id, softwareLicense[id, softwareDescription[longDescription]]], tagReferences[tagId, tag[name]], primaryIpAddress, primaryBackendIpAddress]").getVirtualGuests
for x in 0..list_of_virtual_machines.length - 1
virtual_machines_count_index = virtual_machines_count_index + 1
if virtual_machines_count_index == virtual_machines_count
pp("Finished retrieving " + virtual_machines_count.to_s + " virtual machines")
end
end
end
The crash looks like (the process.rb line 552 contains the getVirtualGuests call):
/opt/cds/ruby/lib/ruby/2.1.0/xmlrpc/client.rb:271:in `call': An error has occurred while processing your request. Please try again later. (XMLRPC::FaultException)
from /opt/cds/ruby/gems/gems/softlayer_api-3.1.0/lib/softlayer/Service.rb:267:in `call_softlayer_api_with_params'
from /opt/cds/ruby/gems/gems/softlayer_api-3.1.0/lib/softlayer/APIParameterFilter.rb:194:in `method_missing'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:552:in `block (5 levels) in retrieve_softlayer_inventory_information'
from /opt/cds/ruby/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/core_ext/range/each.rb:7:in `each'
from /opt/cds/ruby/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/core_ext/range/each.rb:7:in `each_with_time_with_zone'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:551:in `block (4 levels) in retrieve_softlayer_inventory_information'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:511:in `each'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:511:in `block (3 levels) in retrieve_softlayer_inventory_information'
from /opt/cds/ruby/gems/gems/sensu-em-2.5.1/lib/eventmachine.rb:1054:in `call'
from /opt/cds/ruby/gems/gems/sensu-em-2.5.1/lib/eventmachine.rb:1054:in `block in spawn_threadpool'
Thank you in advance for any help.
The cause of this exception could be due to the amount of data that is attempting to be retrieved at once.
As first suggestion I would tell you, that you use “result limits” in your script. But I can see that you are using this. In that case, you may reduce the values of your result limits.
Other reason could be the query generated from that “object masks” is too intensive and is causing the failures. In that case it is recommended that you please reduce the values in the “object masks”, maybe splitting the retrieval of all those properties into multiple calls and additionally adding a cool down period in the iteration of their virtual guests.
This is pseudo code what I trying to explain:
for x in myVsis:
vsiId = myVsis.id
tempVsiObject1 = getVsi('[property1,property2, property3, property4]') // Call 1 with reduced properties in the mask
tempVsiObject2 = getVsi('[property5, property6, property7 ]') // Call 2 with reduced properties in the mask
tempVsiObject3 = getVsi('[property8[property9[property10[property11]]]]') // Call 3 with reduced properties in the mask
vsi = merge_objects(tempVsiObject1, tempVsiObject2, tempVsiObject3)
sleep(1) // cool down 1 second before moving to the next VSI
I hope this alternative help you, where the result will have in lighter queries each time.
I am trying to search a table for specific a specific value using Ruby and Selenium-webdriver. I have a method that works but takes a lot of time for some reason. It is a one row table and the page HTML looks like this:
<div id="permitGridContainer">
<table id="calendar" class="items" style="width:430px;" name="calendar">
<thead>
<tbody>
<tr>
<td id="avail1" class="status r slct" onmouseout="return nd();" onmouseover="return overlib("Available Quota<br>River Launches : 0 of 4");">
<div class="permitStatus">R</div>
</td>
<td id="avail2" class="status r" onmouseout="return nd();" onmouseover="return overlib("Available Quota<br>River Launches : 0 of 4");">
<div class="permitStatus">R</div>
</td>
<td id="avail3" class="status a" onmouseout="return nd();" onmouseover="return overlib("Available Quota<br>River Launches : 89 of 99");">
<a onclick="javascript:setNewArrivalDate("Sun Sep 06 2015", 2);return false;" href="#">
A
<br>
<small>89</small>
</a>
</td>
<td id="avail4" class="status a" onmouseout="return nd();" onmouseover="return overlib("Available Quota<br>River Launches : 97 of 99");">
</tr>
</tbody>
</table>
</div>
... I shortened the table it has 14 columns.
I am looking for a column that has an Item available and I am checking the class for this, but the text also changes so there are other things I could look for.
This is the code I am using, but it visibly slow. I used puts statements to see the progress. My sense is that is has to do with time accessing the element. So I was hoping there is a better way to process the table quickly. Thank you.
for j in 1..days_to_check[i]
check_avail = driver.find_element(id: "avail#{j}")
check_availclass = check_avail.attribute ("class")
if check_availclass == "status a" or check_availclass == "status a slct"
#process if
end
Depending on your comment I would suggest to use the following xpath. I find this is often easier and feasible to use better xpath than looping though the html table
//td[(#class='status a') or (#class='status A')]
This xpath finds the class with status a or status A