Watir Webdriver <script> Element exists? - webdriver

I'm attempting to determine after a page loads whether text within a script may be located using Watir WebDriver. I am using Watir-WebDriver to automate our test effort. I cannot figure out how to locate the element and verify the value. Any help?
<script><!--
...
s.events="event9"
...
//--></script>
So, I guess I'm wondering is it possible to search for text within a HTML script using watir webdriver?
Thank you in advance.
UPDATE: Below is the script.
require "rubygems"
require "watir-webdriver"
require "watir-webdriver-performance"
require "rspec"
require "headless"
include Watir
require 'logger'
#path store file: script, data file, logs
path = File.dirname(__FILE__)
#create log file
name_log = 'TEST_0001_bsro_validation_suite'
file = File.open(path + '/logs/' + name_log + '_logFile.log', File::WRONLY | File::APPEND | File::CREAT)
logger = Logger.new(file)
logger.info("=> TEST: 0004_bsro_validation")
#open internet browser
browser = Watir::Browser.new :ff
#go to rebrand website with login info. this may need to be removed.
test_site = 'http://*****:*****#fcac-rebrand.laughlin.com/'
browser.goto(test_site)
load_secs = browser.performance.summary[:response_time]
logger.info("=> Page Load Time: #{load_secs}")
zipcode_input = browser.text_field(:id => 'universal-selectorZip')
# select year; progressive selection
year_select = browser.select_list(:id => 'universal-year')
browser.select_list(:id => 'universal-year', :disabled => 'disabled').wait_while_present
if year_select.exists?
year_select.select '2010'
else
logger.info("=> ERROR: Year Select Not Available")
end
# select make; progressive selection
make_select = browser.select_list(:id => 'universal-make')
browser.select_list(:id => 'universal-make', :disabled => 'disabled').wait_while_present
if make_select.exists?
make_select.select 'Volkswagen'
else
logger.info("=> ERROR: Make Select Not Available")
end
# select model; progressive selection
model_select = browser.select_list(:id => 'universal-model')
browser.select_list(:id => 'universal-model', :disabled => 'disabled').wait_while_present
if model_select.exists?
model_select.select 'Jetta'
else
logger.info("=> ERROR: Model Select Not Available")
end
# select submodel; progressive selection
submodel_select = browser.select_list(:id => 'universal-submodel')
browser.select_list(:id => 'universal-submodel', :disabled => 'disabled').wait_while_present
if submodel_select.exists?
submodel_select.select '2.0T TDI Sedan'
else
logger.info("=> ERROR: Submodel Select Not Available")
end
# input zip code; progressive selection
if zipcode_input.exists?
zipcode_input.set '53202'
else
logger.info("=> ERROR: ZIP Code Select Not Available")
end
browser.button(:id => 'universal-submit-tires-quote').click
browser.script.html.include? "event49"
browser.close
I should add that the event is event49 not 9 in this case. Thanks!

Zeljko has the right approach. However, it would fail if/when there are multiple scripts on the page and the one you want is not first.
If there are multiple script elements, you will have to iterate over them to see if one of the scripts has the value.
browser.scripts.any?{ |s| s.html.include? "event9" }
#=> true

This should do it:
browser.script.html.include? "event9"
#=> true

Related

How to get count of certain record saved in Uppercase, lower or a combination using LINQ query

I need to get the count of IN / in / In from SoccerStatus regardless if the records are saved in upper case, lower case or a combination of both ie IN or in or In from SQLite database in Xamarin Forms. How can I achieve that ?
var count_in = (from x in conn.Table<SoccerAvailability>().Where(x => x.SoccerStatus == IN) select x).Count();
Use string.Equals and tell it to ignore case...
var count_in = (from x in conn.Table<SoccerAvailability>().Where(x => string.Equals(x.SoccerStatus, "IN", StringComparison.OrdinalIgnoreCase)) select x).Count();
EDIT: Per your comment I see that the Linq provider you're using doesn't support string.Equals. You can try the following which should be more portable but possibly a bit slower...
var count_in = (from x in conn.Table<SoccerAvailability>().Where(x => x.SoccerStatus.ToUpper() == "IN") select x).Count();

How can I see the SQL generated by SQLite.NET PCL in Xamarin Studio?

I researched this and all I can find is a suggestion to turn on .Trace = true like this:
db1 = DependencyService.Get<ISQLite>().GetConnection();
db1.Trace = true;
I also tried this:
db2.Trace = true;
var categories = db2.Query<Category>("SELECT * FROM Category ORDER BY Name").ToList();
Debug.WriteLine("xxxx");
Well I did this and then restarted the application. When I view the Application output I just see information on threads started and the xxxx but don't see any SQL trace information.
Can anyone give me advice on this. Thanks
You need to set Trace and Tracer (action) properties on your SQLiteConnection to print queries to output:
db.Tracer = new Action<string>(q => Debug.WriteLine(q));
db.Trace = true;
Look in the Application Output window for lines that begin Executing
Example Output after setting Trace to true:
Executing: create table if not exists "Valuation"(
"Id" integer primary key autoincrement not null ,
"StockId" integer ,
"Time" datetime ,
"Price" float )
Executing Query: pragma table_info("Valuation")
Executing: create index if not exists "Valuation_StockId" on "Valuation"("StockId")
Executing: insert into "Stock"("Symbol") values (?)
Executing Query: select * from "Stock" where ("Symbol" like (? || '%'))
0: A
Ref: https://github.com/praeclarum/sqlite-net/blob/38a5ae07c886d6f62cecd8fdeb8910d9b5a77546/src/SQLite.cs
The SQLite PCL uses Debug.WriteLine which means that the logs are only included in Debug builds of the PCL.
Remove your nuget reference to the sqlite.net PCL (leave the native reference), and instead add SQLite.cs as a class to your project, and execute a debug build, with the Trace flag set, and you'll see the tracing.
I didn't have to do anything special other than include the SQLite.cs file in my Xamarin iOS project for this to work:
using (var conn = new SQLite.SQLiteConnection("mydb.sqlite") { Trace = true }) {
var rows = conn.Table<PodcastMetadata>().Where(row => row.DurationMinutes < 10).Select(row => new { row.Title });
foreach (var row in rows) {
Debug.WriteLine(row);
}
}
Output:
Executing Query: select * from "PodcastMetadata" where ("DurationMinutes" < ?)
0: 10

Conditional classname and text (Rails)

I'm pretty new to Rails and trying some basic stuff like conditional classes.
On the 'show' view I have an element that changes styling depending on the stock availability, but also the text changes accordingly.
People keep saying the controller should be as small as possible, but placing this conditional in the view also feels dirty. Is this really the best way?
Current controller:
def show
#tyre = Tyres::Tyre.find_by_id(params[:id])
if #tyre.in_stock
#availability = I18n.t("products.filter.other.in_stock")
#availability_class = 'i-check-circle color--success'
else
#availability = I18n.t("products.filter.other.not_in_stock")
#availability_class = 'i-cross-circle color--important'
end
end
Edit:
Controller:
def show
#tyre = Tyres::Tyre.find_by_id(params[:id])
if #tyre.in_stock
#availability_append = ".in_stock"
else
#availability_append = ".not_in_stock"
end
#availability = I18n.t("products.filter.other#{#availability_append}")
end
View:
.xs-12.description__status
%i{class: (#tyre.in_stock? ? 'i-check-circle color--success' : 'i-cross-circle color--important')}
= #availability
You can clean your controller tyres_controller.rb (i suppose) method,
def show
#tyre = Tyre.find(params[:id]) # I believe you have a model named 'tyre'
end
Then, there will be a file named tyres_helper.rb in your myproject/app/helpers/. Put the following code there,
def tyre_availability(tyre) # it'll return an array with two values, first one is class name, second one is localized value
if tyre.in_stock
return 'i-check-circle color--success', I18n.t("products.filter.other.in_stock")
else
return 'i-cross-circle color--important', I18n.t("products.filter.other.not_in_stock")
end
end
and, in the view you can use,
.xs-12.description__status
%i{:class => tyre_availability(#tyre)[0]}
= tyre_availability(#tyre)[1]

Nokogiri doesn't work using css selector

My code:
require 'rubygems'
require 'nokogiri'
require 'open-uri'
PAGE_URL = "http://www.whoscored.com/Teams/1799/Fixtures/Spain-Almeria"
page = Nokogiri::HTML(open(PAGE_URL))
CSS_SELECTOR = "a.match-link.match-report.rc"
links = page.css(CSS_SELECTOR)
puts links.length # => RESULT = 0
puts links[0].text # => RESULT = none
puts links[0]["href"] # => RESULT = ./read_stats.rb:15:in `<main>': undefined method `text' for nil:NilClass (NoMethodError)
The results should be:
1
Match Report
/Matches/738463/MatchReport
But my results are:
0
./read_stats.rb:15:in `<main>': undefined method `text' for nil:NilClass (NoMethodError)
It doesn't work, and I dont see the problem...
Thanks.
You need to render the page before you can scrape it.
require 'watir-webdriver'
require 'nokogiri'
$browser = Watir::Browser.start "http://www.whoscored.com/Teams/1799/Fixtures/Spain-Almeria"
$page_html = Nokogiri::HTML.parse($browser.html)
$page_html.css("td[#class='toolbar right']").each do |me|
print "#{me.count}\n#{me.text}\n#{me.css("a").map{|link| link['href']}[0]}\n\n"
end
Try out watir.com

RefineryCMS: apply bootstrap styles to navigation menu

I have upgraded Refinery CMS to the newest version (2.1.0), where there is a new approach in rendering the navigation menu :
(in partial _header.html.erb)
<%= Refinery::Pages::MenuPresenter.new(refinery_menu_pages, self).to_html %>
The older version of the same partial :
<%= render(:partial => "/refinery/menu", :locals => {
:dom_id => 'menu',
:css => 'menu'
}) %>
How could I add bootstrap styles to the navbar using MenuPresenter?
It can be done, but the solution is not pretty because the Menu Presenter in Refinery 2.1 doesn't support all the right CSS options out of the box. But with a bit of perseverance, this is roughly what to do:
Firstly, create a new blank file here: config/initializers/refinery/monkey_patch_menu_presenter.rb
In this patch file, paste in the contents of this updated version of the menu presenter (published October 2013): menu_presenter.rb
Next, based on the instructions in section 5 of the menu presenter guide, in your app/helpers/application_helper.rb file, add a new method called navigation_menu:
def navigation_menu
presenter = Refinery::Pages::MenuPresenter.new(refinery_menu_pages, self)
presenter.css = "navbar-inner"
presenter.menu_tag = :div
presenter.list_tag_css = "nav"
presenter.selected_css = "active"
presenter.first_css = ""
presenter.last_css = ""
presenter.max_depth = 0 # prevents dropdown menus, which don't render correctly
presenter
end
Finally, in your app/views/refinery/_header.html.erb file (use $ bundle exec rake refinery:override view=refinery/_header if it doesn't exist), replace the call for:
<%= Refinery::Pages::MenuPresenter.new(refinery_menu_pages, self).to_html %>
with:
<div class="navbar">
<%= navigation_menu.to_html %>
</div>
Ensure that you have the loaded the Bootstrap CSS/JS files and have wrapped the whole page in a <div class="container"> element. Then restart your application for the patch to take affect and hopefully you'll see a familiar bootstrap navigation bar.
Good luck!
Martyn.
Here a version of above menu_presenter.rb that renders sub-menus as well
(This if for Bootstrap 3, RefineryCMS 2.1.1):
require 'active_support/core_ext/string'
require 'active_support/configurable'
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/url_helper'
module Refinery
module Pages
class MenuPresenter
include ActionView::Helpers::TagHelper
include ActionView::Helpers::UrlHelper
include ActiveSupport::Configurable
config_accessor :roots, :menu_tag, :list_tag, :list_item_tag, :css, :dom_id,
:max_depth, :selected_css, :first_css, :last_css, :list_tag_css,
:link_tag_css
self.dom_id = 'menu'
self.css = "collapse navbar-collapse"
self.menu_tag = :div
self.list_tag = :ul
self.list_item_tag = :li
self.selected_css = 'active'
self.first_css = :first
self.last_css = :last
self.list_tag_css = "nav navbar-nav"
def roots
config.roots.presence || collection.roots
end
attr_accessor :context, :collection
delegate :output_buffer, :output_buffer=, :to => :context
def initialize(collection, context)
#collection = collection
#context = context
end
def to_html
render_menu(roots) if roots.present?
end
private
def render_menu(items)
content_tag(menu_tag, :id => dom_id, :class => css) do
render_menu_items(items)
end
end
def render_menu_items(menu_items)
if menu_items.present?
content_tag(list_tag, :class => list_tag_css) do
menu_items.each_with_index.inject(ActiveSupport::SafeBuffer.new) do |buffer, (item, index)|
buffer << render_menu_item(item, index)
end
end
end
end
def render_menu_items_children(menu_items)
if menu_items.present?
content_tag(list_tag, :class => 'dropdown-menu') do
menu_items.each_with_index.inject(ActiveSupport::SafeBuffer.new) do |buffer, (item, index)|
buffer << render_menu_item(item, index)
end
end
end
end
def render_menu_item_link_dropdown(menu_item)
link_to( menu_item.title, context.refinery.url_for(menu_item.url), class: "dropdown-toggle", data: {toggle:"dropdown", target: "#"})
end
def render_menu_item_link(menu_item)
link_to(menu_item.title, context.refinery.url_for(menu_item.url), :class => link_tag_css)
end
def render_menu_item(menu_item, index)
content_tag(list_item_tag, :class => menu_item_css(menu_item, index)) do
buffer = ActiveSupport::SafeBuffer.new
# Check for sub menu
menu_item_children(menu_item).empty? ? buffer << render_menu_item_link(menu_item) : buffer << render_menu_item_link_dropdown(menu_item)
buffer << render_menu_items_children(menu_item_children(menu_item))
buffer
end
end
# Determines whether any item underneath the supplied item is the current item according to rails.
# Just calls selected_item? for each descendant of the supplied item
# unless it first quickly determines that there are no descendants.
def descendant_item_selected?(item)
item.has_children? && item.descendants.any?(&method(:selected_item?))
end
def selected_item_or_descendant_item_selected?(item)
selected_item?(item) || descendant_item_selected?(item)
end
# Determine whether the supplied item is the currently open item according to Refinery.
def selected_item?(item)
path = context.request.path
path = path.force_encoding('utf-8') if path.respond_to?(:force_encoding)
# Ensure we match the path without the locale, if present.
if %r{^/#{::I18n.locale}/} === path
path = path.split(%r{^/#{::I18n.locale}}).last.presence || "/"
end
# First try to match against a "menu match" value, if available.
return true if item.try(:menu_match).present? && path =~ Regexp.new(item.menu_match)
# Find the first url that is a string.
url = [item.url]
url << ['', item.url[:path]].compact.flatten.join('/') if item.url.respond_to?(:keys)
url = url.last.match(%r{^/#{::I18n.locale.to_s}(/.*)}) ? $1 : url.detect{|u| u.is_a?(String)}
# Now use all possible vectors to try to find a valid match
[path, URI.decode(path)].include?(url) || path == "/#{item.original_id}"
end
def menu_item_css(menu_item, index)
css = []
css << selected_css if selected_item_or_descendant_item_selected?(menu_item)
css << "dropdown" unless menu_item_children(menu_item).empty?
css << first_css if index == 0
css << last_css if index == menu_item.shown_siblings.length
css.reject(&:blank?).presence
end
def menu_item_children(menu_item)
within_max_depth?(menu_item) ? menu_item.children : []
end
def within_max_depth?(menu_item)
!max_depth || menu_item.depth < max_depth
end
end
end
end

Resources