Skip to content

Commit

Permalink
Add smaller isDisplayed and getAttribute atoms
Browse files Browse the repository at this point in the history
  • Loading branch information
twalpole committed May 14, 2019
1 parent 62230c7 commit 6189f45
Show file tree
Hide file tree
Showing 18 changed files with 736 additions and 24 deletions.
14 changes: 14 additions & 0 deletions Rakefile
Expand Up @@ -65,6 +65,20 @@ task :travis do
Rake::Task[:cucumber].invoke
end

task :build_js do
require 'uglifier'
Dir.glob('./lib/capybara/selenium/atoms/src/*.js').each do |fn|
js = ::Uglifier.compile(
File.read(fn),
compress: {
negate_iife: false, # Negate immediately invoked function expressions to avoid extra parens
side_effects: false # Pass false to disable potentially dropping functions marked as "pure"
}
)[0...-1]
File.write("./lib/capybara/selenium/atoms/#{File.basename(fn).gsub('.js', '.min.js')}", js)
end
end

task :release do
version = Capybara::VERSION
puts "Releasing #{version}, y/n?"
Expand Down
1 change: 1 addition & 0 deletions capybara.gemspec
Expand Up @@ -33,6 +33,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency('rack', ['>= 1.6.0'])
s.add_runtime_dependency('rack-test', ['>= 0.6.3'])
s.add_runtime_dependency('regexp_parser', ['~>1.2'])
s.add_runtime_dependency('uglifier')
s.add_runtime_dependency('xpath', ['~>3.2'])

s.add_development_dependency('byebug') unless RUBY_PLATFORM == 'java'
Expand Down
1 change: 1 addition & 0 deletions lib/capybara/selenium/atoms/getAttribute.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/capybara/selenium/atoms/isDisplayed.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

161 changes: 161 additions & 0 deletions lib/capybara/selenium/atoms/src/getAttribute.js
@@ -0,0 +1,161 @@
(function(){
var BOOLEAN_PROPERTIES = [
"allowfullscreen",
"allowpaymentrequest",
"allowusermedia",
"async",
"autofocus",
"autoplay",
"checked",
"compact",
"complete",
"controls",
"declare",
"default",
"defaultchecked",
"defaultselected",
"defer",
"disabled",
"ended",
"formnovalidate",
"hidden",
"indeterminate",
"iscontenteditable",
"ismap",
"itemscope",
"loop",
"multiple",
"muted",
"nohref",
"nomodule",
"noresize",
"noshade",
"novalidate",
"nowrap",
"open",
"paused",
"playsinline",
"pubdate",
"readonly",
"required",
"reversed",
"scoped",
"seamless",
"seeking",
"selected",
"truespeed",
"typemustmatch",
"willvalidate"
];

var PROPERTY_ALIASES = {
"class": "className",
"readonly": "readOnly"
};

function isSelectable(element){
var tagName = element.tagName.toUpperCase();

if (tagName == "OPTION"){
return true;
}

if (tagName == "INPUT") {
var type = element.type.toLowerCase();
return type == "checkbox" || type == "radio";
}

return false;
}

function isSelected(element){
var propertyName = "selected";
var type = element.type && element.type.toLowerCase();
if ("checkbox" == type || "radio" == type) {
propertyName = "checked";
}

return !!element[propertyName];
}

function getAttributeValue(element, name){
var attr = element.getAttributeNode(name);
return (attr && attr.specified) ? attr.value : null;
}

return function get(element, attribute){
var value = null;
var name = attribute.toLowerCase();

if ("style" == name) {
value = element.style;

if (value && (typeof value != "string")) {
value = value.cssText;
}

return value;
}

if (("selected" == name || "checked" == name) &&
isSelectable(element)) {
return isSelected(element) ? "true" : null;
}

tagName = element.tagName.toUpperCase();

// The property is consistent. Return that in preference to the attribute for links and images.
if (((tagName == "IMG") && name == "src") ||
((tagName == "A") && name == "href")) {
value = getAttributeValue(element, name);
if (value) {
// We want the full URL if present
value = element[name];
}
return value;
}

if ("spellcheck" == name) {
value = getAttributeValue(element, name);
if (!value === null) {
if (value.toLowerCase() == "false") {
return "false";
} else if (value.toLowerCase() == "true") {
return "true";
}
}
// coerce the property value to a string
return element[name] + "";
}
var propName = PROPERTY_ALIASES[attribute] || attribute;
if (BOOLEAN_PROPERTIES.some(function(prop){ prop == name })) {
value = getAttributeValue(element, name);
value = !(value === null) || element[propName];
return value ? "true" : null;
}
var property;
try {
property = element[propName]
} catch (e) {
// Leaves property undefined or null
}
// 1- Call getAttribute if getProperty fails,
// i.e. property is null or undefined.
// This happens for event handlers in Firefox.
// For example, calling getProperty for 'onclick' would
// fail while getAttribute for 'onclick' will succeed and
// return the JS code of the handler.
//
// 2- When property is an object we fall back to the
// actual attribute instead.
// See issue http://code.google.com/p/selenium/issues/detail?id=966
if ((property == null) || (typeof property == "object") || (typeof property == "function")) {
value = getAttributeValue(element, attribute);
} else {
value = property;
};

// The empty string is a valid return value.
return value != null ? value.toString() : null;
};
})()

0 comments on commit 6189f45

Please sign in to comment.