selenium-webdriver 3.0.0.beta3.1 → 3.0.0.beta4.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,22 @@
1
+ 3.0.0.beta4 (2016-09-29)
2
+ ===================
3
+
4
+ Ruby:
5
+ * Remove support for deprecated driver options
6
+ * Add support for latest driver options
7
+ * Add support for :port parameter for launching driver
8
+ * Add support for :service_args parameter for driver command line switches
9
+ * Improve reliability by increasing service shutdown timeout (#2815; thanks John Barbuto )

10
+
11
+ Firefox:
12
+ * Add support for :firefox_options in geckodriver
13
+
14
+ Safari:
15
+ * Remove support for legacy Safari driver (use Apple's driver built in to Safari 10+)
16
+
17
+ Chrome:
18
+ * Set chromedriver to not log by default
19
+
1
20
  3.0.0.beta3.1 (2016-09-03)
2
21
  ===================
3
22
 
@@ -1,9 +1,11 @@
1
- function(){return function(){var e=this;function f(a){return"string"==typeof a};function l(a,b){this.a=m[a]||n;this.message=b||"";var c=this.a.replace(/((?:^|\s+)[a-z])/g,function(a){return a.toUpperCase().replace(/^[\s\xa0]+/g,"")}),d=c.length-5;if(0>d||c.indexOf("Error",d)!=d)c+="Error";this.name=c;c=Error(this.message);c.name=this.name;this.stack=c.stack||""}
2
- (function(){var a=Error;function b(){}b.prototype=a.prototype;l.b=a.prototype;l.prototype=new b;l.prototype.constructor=l;l.a=function(c,b,g){for(var k=Array(arguments.length-2),h=2;h<arguments.length;h++)k[h-2]=arguments[h];return a.prototype[b].apply(c,k)}})();var n="unknown error",m={15:"element not selectable",11:"element not visible"};m[31]=n;m[30]=n;m[24]="invalid cookie domain";m[29]="invalid element coordinates";m[12]="invalid element state";m[32]="invalid selector";m[51]="invalid selector";
3
- m[52]="invalid selector";m[17]="javascript error";m[405]="unsupported operation";m[34]="move target out of bounds";m[27]="no such alert";m[7]="no such element";m[8]="no such frame";m[23]="no such window";m[28]="script timeout";m[33]="session not created";m[10]="stale element reference";m[21]="timeout";m[25]="unable to set cookie";m[26]="unexpected alert open";m[13]=n;m[9]="unknown command";l.prototype.toString=function(){return this.name+": "+this.message};var p=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};
4
- function q(a,b){for(var c=0,d=p(String(a)).split("."),g=p(String(b)).split("."),k=Math.max(d.length,g.length),h=0;0==c&&h<k;h++){var R=d[h]||"",ga=g[h]||"",ha=RegExp("(\\d*)(\\D*)","g"),ia=RegExp("(\\d*)(\\D*)","g");do{var t=ha.exec(R)||["","",""],u=ia.exec(ga)||["","",""];if(0==t[0].length&&0==u[0].length)break;c=r(0==t[1].length?0:parseInt(t[1],10),0==u[1].length?0:parseInt(u[1],10))||r(0==t[2].length,0==u[2].length)||r(t[2],u[2])}while(0==c)}return c}function r(a,b){return a<b?-1:a>b?1:0};var v;a:{var w=e.navigator;if(w){var x=w.userAgent;if(x){v=x;break a}}v=""}function y(a){return-1!=v.indexOf(a)};function aa(a,b){for(var c=a.length,d=f(a)?a.split(""):a,g=0;g<c;g++)g in d&&b.call(void 0,d[g],g,a)};function z(){return y("iPhone")&&!y("iPod")&&!y("iPad")};function A(){return y("Opera")||y("OPR")}function B(){return(y("Chrome")||y("CriOS"))&&!A()&&!y("Edge")};var C=A(),D=y("Trident")||y("MSIE"),E=y("Edge"),F=y("Gecko")&&!(-1!=v.toLowerCase().indexOf("webkit")&&!y("Edge"))&&!(y("Trident")||y("MSIE"))&&!y("Edge"),ba=-1!=v.toLowerCase().indexOf("webkit")&&!y("Edge");function ca(){var a=v;if(F)return/rv\:([^\);]+)(\)|;)/.exec(a);if(E)return/Edge\/([\d\.]+)/.exec(a);if(D)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(ba)return/WebKit\/(\S+)/.exec(a)}function G(){var a=e.document;return a?a.documentMode:void 0}
5
- var H=function(){if(C&&e.opera){var a;var b=e.opera.version;try{a=b()}catch(c){a=b}return a}a="";(b=ca())&&(a=b?b[1]:"");return D&&(b=G(),null!=b&&b>parseFloat(a))?String(b):a}(),I={},J=e.document,K=J&&D?G()||("CSS1Compat"==J.compatMode?parseInt(H,10):5):void 0;!F&&!D||D&&9<=Number(K)||F&&(I["1.9.1"]||(I["1.9.1"]=0<=q(H,"1.9.1")));D&&(I["9"]||(I["9"]=0<=q(H,"9")));var da=y("Firefox"),ea=z()||y("iPod"),fa=y("iPad"),L=y("Android")&&!(B()||y("Firefox")||A()||y("Silk")),ja=B(),M=y("Safari")&&!(B()||y("Coast")||A()||y("Edge")||y("Silk")||y("Android"))&&!(z()||y("iPad")||y("iPod"));var ka={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},N={IMG:" ",BR:"\n"};function la(a,b,c){if(!(a.nodeName in ka))if(3==a.nodeType)c?b.push(String(a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in N)b.push(N[a.nodeName]);else for(a=a.firstChild;a;)la(a,b,c),a=a.nextSibling};function O(a){return(a=a.exec(v))?a[1]:""}var ma=function(){if(da)return O(/Firefox\/([0-9.]+)/);if(D||E||C)return H;if(ja)return O(/Chrome\/([0-9.]+)/);if(M&&!(z()||y("iPad")||y("iPod")))return O(/Version\/([0-9.]+)/);if(ea||fa){var a;if(a=/Version\/(\S+).*Mobile\/(\S+)/.exec(v))return a[1]+"."+a[2]}else if(L)return(a=O(/Android\s+([0-9.]+)/))?a:O(/Version\/([0-9.]+)/);return""}();var na;function P(a){oa?na(a):L?q(pa,a):q(ma,a)}var oa=function(){if(!F)return!1;var a=e.Components;if(!a)return!1;try{if(!a.classes)return!1}catch(g){return!1}var b=a.classes,a=a.interfaces,c=b["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator),d=b["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo).version;na=function(a){c.compare(d,""+a)};return!0}(),Q;if(L){var qa=/Android\s+([0-9\.]+)/.exec(v);Q=qa?qa[1]:"0"}else Q="0";
6
- var pa=Q,ra=D&&!(8<=Number(K)),sa=D&&!(9<=Number(K));L&&P(2.3);L&&P(4);M&&P(6);function S(a,b){b=b.toLowerCase();if("style"==b)return ta(a.style.cssText);if(ra&&"value"==b&&T(a,"INPUT"))return a.value;if(sa&&!0===a[b])return String(a.getAttribute(b));var c=a.getAttributeNode(b);return c&&c.specified?c.value:null}var ua=/[;]+(?=(?:(?:[^"]*"){2})*[^"]*$)(?=(?:(?:[^']*'){2})*[^']*$)(?=(?:[^()]*\([^()]*\))*[^()]*$)/;
7
- function ta(a){var b=[];aa(a.split(ua),function(a){var d=a.indexOf(":");0<d&&(a=[a.slice(0,d),a.slice(d+1)],2==a.length&&b.push(a[0].toLowerCase(),":",a[1],";"))});b=b.join("");return b=";"==b.charAt(b.length-1)?b:b+";"}function U(a,b){var c;if(c=ra&&"value"==b&&T(a,"OPTION"))c=null===S(a,"value");c?(c=[],la(a,c,!1),c=c.join("")):c=a[b];return c}function T(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}
8
- function va(a){return T(a,"OPTION")?!0:T(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):!1};var wa={"class":"className",readonly:"readOnly"},V="async autofocus autoplay checked compact complete controls declare defaultchecked defaultselected defer disabled draggable ended formnovalidate hidden indeterminate iscontenteditable ismap itemscope loop multiple muted nohref noresize noshade novalidate nowrap open paused pubdate readonly required reversed scoped seamless seeking selected spellcheck truespeed willvalidate".split(" ");function xa(a,b){var c=null,d=b.toLowerCase();if("style"==d)return(c=a.style)&&!f(c)&&(c=c.cssText),c;if(("selected"==d||"checked"==d)&&va(a)){if(!va(a))throw new l(15,"Element is not selectable");var c="selected",g=a.type&&a.type.toLowerCase();if("checkbox"==g||"radio"==g)c="checked";return U(a,c)?"true":null}var k=T(a,"A");if(T(a,"IMG")&&"src"==d||k&&"href"==d)return(c=S(a,d))&&(c=U(a,d)),c;if("spellcheck"==d){c=S(a,d);if(null!==c){if("false"==c.toLowerCase())return"false";if("true"==c.toLowerCase())return"true"}return U(a,
9
- d)+""}k=wa[b]||b;a:if(f(V))d=f(d)&&1==d.length?V.indexOf(d,0):-1;else{for(var h=0;h<V.length;h++)if(h in V&&V[h]===d){d=h;break a}d=-1}if(0<=d)return(c=null!==S(a,b)||U(a,k))?"true":null;try{g=U(a,k)}catch(R){}(d=null==g)||(d=typeof g,d="object"==d&&null!=g||"function"==d);d?c=S(a,b):c=g;return null!=c?c.toString():null}var W=["_"],X=e;W[0]in X||!X.execScript||X.execScript("var "+W[0]);for(var Y;W.length&&(Y=W.shift());){var Z;if(Z=!W.length)Z=void 0!==xa;Z?X[Y]=xa:X[Y]?X=X[Y]:X=X[Y]={}};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null,document:typeof window!='undefined'?window.document:null}, arguments);}
1
+ function(){return function(){var aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,c,b){if(b.get||b.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[c]=b.value)},ba="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global?global:this;
2
+ function e(a,c){if(c){for(var b=ba,d=a.split("."),f=0;f<d.length-1;f++){var h=d[f];h in b||(b[h]={});b=b[h]}d=d[d.length-1];f=b[d];h=c(f);h!=f&&null!=h&&aa(b,d,{configurable:!0,writable:!0,value:h})}}
3
+ e("String.prototype.repeat",function(a){return a?a:function(a){var b;if(null==this)throw new TypeError("The 'this' value for String.prototype.repeat must not be null or undefined");b=this+"";if(0>a||1342177279<a)throw new RangeError("Invalid count value");a|=0;for(var d="";a;)if(a&1&&(d+=b),a>>>=1)b+=b;return d}});e("Math.sign",function(a){return a?a:function(a){a=Number(a);return!a||isNaN(a)?a:0<a?1:-1}});var g=this;function l(a){return"string"==typeof a};function m(a,c){this.a=n[a]||p;this.message=c||"";var b=this.a.replace(/((?:^|\s+)[a-z])/g,function(a){return a.toUpperCase().replace(/^[\s\xa0]+/g,"")}),d=b.length-5;if(0>d||b.indexOf("Error",d)!=d)b+="Error";this.name=b;b=Error(this.message);b.name=this.name;this.stack=b.stack||""}
4
+ (function(){var a=Error;function c(){}c.prototype=a.prototype;m.b=a.prototype;m.prototype=new c;m.prototype.constructor=m;m.a=function(b,c,f){for(var h=Array(arguments.length-2),k=2;k<arguments.length;k++)h[k-2]=arguments[k];return a.prototype[c].apply(b,h)}})();var p="unknown error",n={15:"element not selectable",11:"element not visible"};n[31]=p;n[30]=p;n[24]="invalid cookie domain";n[29]="invalid element coordinates";n[12]="invalid element state";n[32]="invalid selector";n[51]="invalid selector";
5
+ n[52]="invalid selector";n[17]="javascript error";n[405]="unsupported operation";n[34]="move target out of bounds";n[27]="no such alert";n[7]="no such element";n[8]="no such frame";n[23]="no such window";n[28]="script timeout";n[33]="session not created";n[10]="stale element reference";n[21]="timeout";n[25]="unable to set cookie";n[26]="unexpected alert open";n[13]=p;n[9]="unknown command";m.prototype.toString=function(){return this.name+": "+this.message};var q=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};
6
+ function r(a,c){for(var b=0,d=q(String(a)).split("."),f=q(String(c)).split("."),h=Math.max(d.length,f.length),k=0;!b&&k<h;k++){var S=d[k]||"",ja=f[k]||"",ka=RegExp("(\\d*)(\\D*)","g"),la=RegExp("(\\d*)(\\D*)","g");do{var t=ka.exec(S)||["","",""],u=la.exec(ja)||["","",""];if(0==t[0].length&&0==u[0].length)break;b=v(0==t[1].length?0:parseInt(t[1],10),0==u[1].length?0:parseInt(u[1],10))||v(0==t[2].length,0==u[2].length)||v(t[2],u[2])}while(!b)}return b}function v(a,c){return a<c?-1:a>c?1:0};var w;a:{var x=g.navigator;if(x){var y=x.userAgent;if(y){w=y;break a}}w=""}function z(a){return-1!=w.indexOf(a)};function ca(a,c){for(var b=a.length,d=l(a)?a.split(""):a,f=0;f<b;f++)f in d&&c.call(void 0,d[f],f,a)};function A(){return z("iPhone")&&!z("iPod")&&!z("iPad")};function B(){return z("Opera")||z("OPR")}function C(){return(z("Chrome")||z("CriOS"))&&!B()&&!z("Edge")};var D=B(),E=z("Trident")||z("MSIE"),F=z("Edge"),G=z("Gecko")&&!(-1!=w.toLowerCase().indexOf("webkit")&&!z("Edge"))&&!(z("Trident")||z("MSIE"))&&!z("Edge"),da=-1!=w.toLowerCase().indexOf("webkit")&&!z("Edge");function ea(){var a=w;if(G)return/rv\:([^\);]+)(\)|;)/.exec(a);if(F)return/Edge\/([\d\.]+)/.exec(a);if(E)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(da)return/WebKit\/(\S+)/.exec(a)}function H(){var a=g.document;return a?a.documentMode:void 0}
7
+ var I=function(){if(D&&g.opera){var a;var c=g.opera.version;try{a=c()}catch(b){a=c}return a}a="";(c=ea())&&(a=c?c[1]:"");return E&&(c=H(),null!=c&&c>parseFloat(a))?String(c):a}(),J={},K=g.document,L=K&&E?H()||("CSS1Compat"==K.compatMode?parseInt(I,10):5):void 0;!G&&!E||E&&9<=Number(L)||G&&(J["1.9.1"]||(J["1.9.1"]=0<=r(I,"1.9.1")));E&&(J["9"]||(J["9"]=0<=r(I,"9")));var fa=z("Firefox"),ga=A()||z("iPod"),ha=z("iPad"),M=z("Android")&&!(C()||z("Firefox")||B()||z("Silk")),ia=C(),N=z("Safari")&&!(C()||z("Coast")||B()||z("Edge")||z("Silk")||z("Android"))&&!(A()||z("iPad")||z("iPod"));var ma={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},na={IMG:" ",BR:"\n"};function oa(a,c,b){if(!(a.nodeName in ma))if(3==a.nodeType)b?c.push(String(a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):c.push(a.nodeValue);else if(a.nodeName in na)c.push(na[a.nodeName]);else for(a=a.firstChild;a;)oa(a,c,b),a=a.nextSibling};function O(a){return(a=a.exec(w))?a[1]:""}var pa=function(){if(fa)return O(/Firefox\/([0-9.]+)/);if(E||F||D)return I;if(ia)return O(/Chrome\/([0-9.]+)/);if(N&&!(A()||z("iPad")||z("iPod")))return O(/Version\/([0-9.]+)/);if(ga||ha){var a=/Version\/(\S+).*Mobile\/(\S+)/.exec(w);if(a)return a[1]+"."+a[2]}else if(M)return(a=O(/Android\s+([0-9.]+)/))?a:O(/Version\/([0-9.]+)/);return""}();var qa;function P(a){ra?qa(a):M?r(sa,a):r(pa,a)}var ra=function(){if(!G)return!1;var a=g.Components;if(!a)return!1;try{if(!a.classes)return!1}catch(f){return!1}var c=a.classes,a=a.interfaces,b=c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator),d=c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo).version;qa=function(a){b.compare(d,""+a)};return!0}(),Q;if(M){var ta=/Android\s+([0-9\.]+)/.exec(w);Q=ta?ta[1]:"0"}else Q="0";
8
+ var sa=Q,ua=E&&!(8<=Number(L)),va=E&&!(9<=Number(L));M&&P(2.3);M&&P(4);N&&P(6);function R(a,c){c=c.toLowerCase();if("style"==c)return wa(a.style.cssText);if(ua&&"value"==c&&T(a,"INPUT"))return a.value;if(va&&!0===a[c])return String(a.getAttribute(c));var b=a.getAttributeNode(c);return b&&b.specified?b.value:null}var xa=/[;]+(?=(?:(?:[^"]*"){2})*[^"]*$)(?=(?:(?:[^']*'){2})*[^']*$)(?=(?:[^()]*\([^()]*\))*[^()]*$)/;
9
+ function wa(a){var c=[];ca(a.split(xa),function(a){var d=a.indexOf(":");0<d&&(a=[a.slice(0,d),a.slice(d+1)],2==a.length&&c.push(a[0].toLowerCase(),":",a[1],";"))});c=c.join("");return c=";"==c.charAt(c.length-1)?c:c+";"}function U(a,c){var b;ua&&"value"==c&&T(a,"OPTION")&&null===R(a,"value")?(b=[],oa(a,b,!1),b=b.join("")):b=a[c];return b}function T(a,c){return!!a&&1==a.nodeType&&(!c||a.tagName.toUpperCase()==c)}
10
+ function ya(a){return T(a,"OPTION")?!0:T(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):!1};var za={"class":"className",readonly:"readOnly"},V="async autofocus autoplay checked compact complete controls declare defaultchecked defaultselected defer disabled draggable ended formnovalidate hidden indeterminate iscontenteditable ismap itemscope loop multiple muted nohref noresize noshade novalidate nowrap open paused pubdate readonly required reversed scoped seamless seeking selected spellcheck truespeed willvalidate".split(" ");function Aa(a,c){var b=null,d=c.toLowerCase();if("style"==d)return(b=a.style)&&!l(b)&&(b=b.cssText),b;if(("selected"==d||"checked"==d)&&ya(a)){if(!ya(a))throw new m(15,"Element is not selectable");var b="selected",f=a.type&&a.type.toLowerCase();if("checkbox"==f||"radio"==f)b="checked";return U(a,b)?"true":null}var h=T(a,"A");if(T(a,"IMG")&&"src"==d||h&&"href"==d)return(b=R(a,d))&&(b=U(a,d)),b;if("spellcheck"==d){b=R(a,d);if(null!==b){if("false"==b.toLowerCase())return"false";if("true"==b.toLowerCase())return"true"}return U(a,
11
+ d)+""}h=za[c]||c;a:if(l(V))d=l(d)&&1==d.length?V.indexOf(d,0):-1;else{for(var k=0;k<V.length;k++)if(k in V&&V[k]===d){d=k;break a}d=-1}if(0<=d)return(b=null!==R(a,c)||U(a,h))?"true":null;try{f=U(a,h)}catch(S){}(d=null==f)||(d=typeof f,d="object"==d&&null!=f||"function"==d);d?b=R(a,c):b=f;return null!=b?b.toString():null}var W=["_"],X=g;W[0]in X||!X.execScript||X.execScript("var "+W[0]);for(var Y;W.length&&(Y=W.shift());){var Z;if(Z=!W.length)Z=void 0!==Aa;Z?X[Y]=Aa:X[Y]?X=X[Y]:X=X[Y]={}};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null,document:typeof window!='undefined'?window.document:null}, arguments);}
@@ -23,27 +23,21 @@ module Selenium
23
23
  # @api private
24
24
  class Bridge < Remote::Bridge
25
25
  def initialize(opts = {})
26
- http_client = opts.delete(:http_client)
26
+ port = opts.delete(:port) || Service::DEFAULT_PORT
27
+ service_args = opts.delete(:service_args) || {}
28
+ if opts[:service_log_path]
29
+ service_args.merge!(service_log_path: opts.delete(:service_log_path))
30
+ end
27
31
 
28
- if opts.key?(:url)
29
- url = opts.delete(:url)
30
- else
31
- @service = Service.new(Chrome.driver_path, Service::DEFAULT_PORT, *extract_service_args(opts))
32
+ unless opts.key?(:url)
33
+ @service = Service.new(Chrome.driver_path, port, *extract_service_args(service_args))
32
34
  @service.start
33
-
34
- url = @service.uri
35
+ opts[:url] = @service.uri
35
36
  end
36
37
 
37
- caps = create_capabilities(opts)
38
-
39
- remote_opts = {
40
- url: url,
41
- desired_capabilities: caps
42
- }
43
-
44
- remote_opts[:http_client] = http_client if http_client
38
+ opts[:desired_capabilities] = create_capabilities(opts)
45
39
 
46
- super(remote_opts)
40
+ super(opts)
47
41
  end
48
42
 
49
43
  def browser
@@ -71,64 +65,39 @@ module Selenium
71
65
  private
72
66
 
73
67
  def create_capabilities(opts)
74
- caps = opts.delete(:desired_capabilities) { Remote::Capabilities.chrome }
75
- args = opts.delete(:args) || opts.delete(:switches)
76
- native_events = opts.delete(:native_events)
77
- verbose = opts.delete(:verbose)
78
- profile = opts.delete(:profile)
79
- detach = opts.delete(:detach)
80
- proxy = opts.delete(:proxy)
81
- no_website_testing_defaults = opts.delete(:no_website_testing_defaults)
82
- prefs = opts.delete(:prefs)
83
-
84
- unless opts.empty?
85
- raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
86
- end
87
-
88
- chrome_options = caps['chromeOptions'] || {}
89
-
90
- if args
91
- unless args.is_a? Array
92
- raise ArgumentError, ':args must be an Array of Strings'
93
- end
68
+ caps = opts.delete(:desired_capabilities) { Remote::Capabilities.chrome }
94
69
 
95
- chrome_options['args'] = args.map(&:to_s)
70
+ chrome_options = caps['chromeOptions'] || caps[:chrome_options] || {}
71
+ chrome_options['binary'] = Chrome.path if Chrome.path
72
+ args = opts.delete(:args) || []
73
+ unless args.is_a? Array
74
+ raise ArgumentError, ':args must be an Array of Strings'
96
75
  end
97
-
98
- if profile
99
- data = profile.as_json
100
-
101
- chrome_options['profile'] = data['zip']
102
- chrome_options['extensions'] = data['extensions']
76
+ chrome_options['args'] = args.map(&:to_s)
77
+ profile = opts.delete(:profile).as_json if opts.key?(:profile)
78
+ if profile && chrome_options['args'].none? { |arg| arg =~ /user-data-dir/}
79
+ chrome_options['args'] << "--user-data-dir=#{profile[:directory]}"
103
80
  end
81
+ chrome_options['extensions'] = profile[:extensions] if profile && profile[:extensions]
82
+ chrome_options['detach'] = true if opts.delete(:detach)
83
+ chrome_options['prefs'] = opts.delete(:prefs) if opts.key?(:prefs)
104
84
 
105
- chrome_options['binary'] = Chrome.path if Chrome.path
106
- chrome_options['nativeEvents'] = true if native_events
107
- chrome_options['verbose'] = true if verbose
108
- chrome_options['detach'] = true if detach
109
- chrome_options['noWebsiteTestingDefaults'] = true if no_website_testing_defaults
110
- chrome_options['prefs'] = prefs if prefs
111
-
112
- caps['chromeOptions'] = chrome_options
113
- caps['proxy'] = proxy if proxy
114
-
115
- # legacy options - for chromedriver < 17.0.963.0
116
- caps['chrome.switches'] = chrome_options['args'] if chrome_options.member?('args')
117
- %w[binary detach extensions nativeEvents noWebsiteTestingDefaults prefs profile verbose].each do |key|
118
- caps["chrome.#{key}"] = chrome_options[key] if chrome_options.member?(key)
119
- end
85
+ caps[:chrome_options] = chrome_options
86
+ caps[:proxy] = opts.delete(:proxy) if opts.key?(:proxy)
87
+ caps[:proxy] ||= opts.delete('proxy') if opts.key?('proxy')
120
88
 
121
89
  caps
122
90
  end
123
91
 
124
- def extract_service_args(opts)
125
- args = []
126
-
127
- if opts.key?(:service_log_path)
128
- args << "--log-path=#{opts.delete(:service_log_path)}"
129
- end
130
-
131
- args
92
+ def extract_service_args(args)
93
+ service_args = []
94
+ service_args << "--log-path=#{args.delete(:service_log_path)}" if args.key?(:service_log_path)
95
+ service_args << "--url-base=#{args.delete(:url_base)}" if args.key?(:url_base)
96
+ service_args << "--port-server=#{args.delete(:port_server)}" if args.key?(:port_server)
97
+ service_args << "--whitelisted-ips=#{args.delete(:whitelisted_ips)}" if args.key?(:whitelisted_ips)
98
+ service_args << "--verbose=#{args.delete(:verbose)}" if args.key?(:whitelisted_ips)
99
+ service_args << "--silent=#{args.delete(:silent)}" if args.key?(:whitelisted_ips)
100
+ service_args
132
101
  end
133
102
  end # Bridge
134
103
  end # Chrome
@@ -27,8 +27,10 @@ module Selenium
27
27
  class Profile
28
28
  include ProfileHelper
29
29
 
30
+ attr_reader :directory
31
+
30
32
  def initialize(model = nil)
31
- @model = verify_model(model)
33
+ @model = verify_model(model)
32
34
  @extensions = []
33
35
  @encoded_extensions = []
34
36
  end
@@ -62,22 +64,24 @@ module Selenium
62
64
  end
63
65
 
64
66
  def layout_on_disk
65
- dir = @model ? create_tmp_copy(@model) : Dir.mktmpdir('webdriver-chrome-profile')
66
- FileReaper << dir
67
+ @directory = @model ? create_tmp_copy(@model) : Dir.mktmpdir('webdriver-chrome-profile')
68
+ FileReaper << @directory
67
69
 
68
- write_prefs_to dir
70
+ write_prefs_to @directory
69
71
 
70
- dir
72
+ @directory
71
73
  end
72
74
 
73
- def as_json(opts = nil)
75
+ def as_json(*)
74
76
  extensions = @extensions.map do |crx_path|
75
77
  File.open(crx_path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
76
78
  end
77
79
 
78
80
  extensions.concat(@encoded_extensions)
79
81
 
80
- super.merge('extensions' => extensions)
82
+ opts = {directory: @directory || layout_on_disk}
83
+ opts[:extensions] = extensions if extensions
84
+ opts
81
85
  end
82
86
 
83
87
  private
@@ -44,7 +44,7 @@ module Selenium
44
44
  listener = opts.delete(:listener)
45
45
 
46
46
  bridge = case browser
47
- when :firefox, :ff, :marionette
47
+ when :firefox, :ff
48
48
  if Remote::W3CCapabilities.w3c?(opts)
49
49
  Firefox::W3CBridge.new(opts)
50
50
  else
@@ -65,11 +65,7 @@ module Selenium
65
65
  when :phantomjs
66
66
  PhantomJS::Bridge.new(opts)
67
67
  when :safari
68
- if Safari::LegacyBridge.legacy?
69
- Safari::LegacyBridge.new(opts)
70
- else
71
- Safari::AppleBridge.new(opts)
72
- end
68
+ Safari::Bridge.new(opts)
73
69
  else
74
70
  raise ArgumentError, "unknown driver: #{browser.inspect}"
75
71
  end
@@ -34,7 +34,7 @@ module Selenium
34
34
  class Service
35
35
  START_TIMEOUT = 20
36
36
  SOCKET_LOCK_TIMEOUT = 45
37
- STOP_TIMEOUT = 5
37
+ STOP_TIMEOUT = 20
38
38
 
39
39
  attr_accessor :host
40
40
 
@@ -45,15 +45,6 @@ module Selenium
45
45
  path
46
46
  end
47
47
  end
48
-
49
- def self.path=(path)
50
- Platform.assert_executable path
51
- @path = path
52
- end
53
-
54
- def self.path
55
- @path ||= nil
56
- end
57
48
  end # Edge
58
49
  end # WebDriver
59
50
  end # Selenium
@@ -26,27 +26,18 @@ module Selenium
26
26
 
27
27
  class Bridge < Remote::W3CBridge
28
28
  def initialize(opts = {})
29
- http_client = opts.delete(:http_client)
30
-
31
- if opts.key?(:url)
32
- url = opts.delete(:url)
33
- else
34
- @service = Service.new(Edge.driver_path, Service::DEFAULT_PORT, *extract_service_args(opts))
29
+ port = opts.delete(:port) || Service::DEFAULT_PORT
30
+ service_args = opts.delete(:service_args) || {}
31
+ unless opts.key?(:url)
32
+ @service = Service.new(Edge.driver_path, port, *extract_service_args(service_args))
35
33
  @service.host = 'localhost' if @service.host == '127.0.0.1'
36
34
  @service.start
37
-
38
- url = @service.uri
35
+ opts[:url] = @service.uri
39
36
  end
40
37
 
41
- caps = create_capabilities(opts)
42
-
43
- remote_opts = {
44
- url: url,
45
- desired_capabilities: caps
46
- }
38
+ opts[:desired_capabilities] ||= Remote::W3CCapabilities.edge
47
39
 
48
- remote_opts[:http_client] = http_client if http_client
49
- super(remote_opts)
40
+ super(opts)
50
41
  end
51
42
 
52
43
  def browser
@@ -72,27 +63,12 @@ module Selenium
72
63
 
73
64
  private
74
65
 
75
- def create_capabilities(opts)
76
- caps = opts.delete(:desired_capabilities) { Remote::W3CCapabilities.edge }
77
- page_load_strategy = opts.delete(:page_load_strategy) || 'normal'
78
-
79
- unless opts.empty?
80
- raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
81
- end
82
-
83
- caps['page_load_strategy'] = page_load_strategy
84
-
85
- caps
86
- end
87
-
88
- def extract_service_args(opts)
89
- args = []
90
-
91
- if opts.key?(:service_log_path)
92
- args << "--log-path=#{opts.delete(:service_log_path)}"
93
- end
94
-
95
- args
66
+ def extract_service_args(args = {})
67
+ service_args = []
68
+ service_args << "–host=#{args[:host]}" if args.key? :host
69
+ service_args << "–package=#{args[:package]}" if args.key? :package
70
+ service_args << "-verbose" if args[:verbose] == true
71
+ service_args
96
72
  end
97
73
  end # Bridge
98
74
  end # Edge
@@ -23,34 +23,19 @@ module Selenium
23
23
  # @api private
24
24
  class Bridge < Remote::Bridge
25
25
  def initialize(opts = {})
26
- port = opts.delete(:port) || DEFAULT_PORT
27
- profile = opts.delete(:profile)
28
- http_client = opts.delete(:http_client)
29
- proxy = opts.delete(:proxy)
30
-
31
- caps = opts.delete(:desired_capabilities) { Remote::Capabilities.firefox }
32
-
33
- Binary.path = caps[:firefox_binary] if caps[:firefox_binary]
26
+ port = opts.delete(:port) || DEFAULT_PORT
27
+ profile = opts.delete(:profile)
34
28
 
35
29
  @launcher = create_launcher(port, profile)
36
-
37
- unless opts.empty?
38
- raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
39
- end
40
-
41
30
  @launcher.launch
31
+ opts[:url] = @launcher.url
42
32
 
43
- caps.proxy = proxy if proxy
44
-
45
- remote_opts = {
46
- url: @launcher.url,
47
- desired_capabilities: caps
48
- }
49
-
50
- remote_opts[:http_client] = http_client if http_client
33
+ caps = opts[:desired_capabilities] ||= Remote::Capabilities.firefox
34
+ caps.proxy = opts.delete(:proxy) if opts.key?(:proxy)
35
+ Binary.path = caps[:firefox_binary] if caps[:firefox_binary]
51
36
 
52
37
  begin
53
- super(remote_opts)
38
+ super(opts)
54
39
  rescue
55
40
  @launcher.quit
56
41
  raise
@@ -23,15 +23,15 @@ module Selenium
23
23
  # @api private
24
24
  class W3CBridge < Remote::W3CBridge
25
25
  def initialize(opts = {})
26
- caps = opts[:desired_capabilities] ||= Remote::W3CCapabilities.firefox
27
- Binary.path = caps[:firefox_binary] if caps[:firefox_binary]
26
+ port = opts.delete(:port) || Service::DEFAULT_PORT
27
+ opts[:desired_capabilities] = create_capabilities(opts)
28
+ service_args = opts.delete(:service_args) || {}
28
29
 
29
- @service = Service.new(Firefox.driver_path, Service::DEFAULT_PORT, *extract_service_args(opts))
30
+ @service = Service.new(Firefox.driver_path, port, *extract_service_args(service_args))
30
31
  @service.start
31
-
32
32
  opts[:url] = @service.uri
33
33
 
34
- super
34
+ super(opts)
35
35
  end
36
36
 
37
37
  def browser
@@ -54,10 +54,25 @@ module Selenium
54
54
 
55
55
  private
56
56
 
57
- def extract_service_args(opts)
58
- service_log_path = opts.delete(:service_log_path)
59
- service_log_path ? ["--log-path=#{service_log_path}"] : []
57
+ def create_capabilities(opts)
58
+ caps = opts.delete(:desired_capabilities) || Remote::W3CCapabilities.firefox
59
+ firefox_options_caps = caps[:firefox_options] || {}
60
+ caps[:firefox_options] = firefox_options_caps.merge(opts[:firefox_options] || {})
61
+
62
+ Binary.path = caps[:firefox_options][:binary] if caps[:firefox_options].key?(:binary)
63
+ caps
60
64
  end
65
+
66
+ def extract_service_args(args = {})
67
+ service_args = []
68
+ service_args << "--binary=#{args[:binary]}" if args.key?(:binary)
69
+ service_args << "–-log=#{args[:log]}" if args.key?(:log)
70
+ service_args << "–-marionette-port=#{args[:marionette_port]}" if args.key?(:marionette_port)
71
+ service_args << "–-host=#{args[:host]}" if args.key?(:host)
72
+ service_args << "–-port=#{args[:port]}" if args.key?(:port)
73
+ service_args
74
+ end
75
+
61
76
  end # W3CBridge
62
77
  end # Firefox
63
78
  end # WebDriver
@@ -26,30 +26,18 @@ module Selenium
26
26
 
27
27
  class Bridge < Remote::Bridge
28
28
  def initialize(opts = {})
29
- caps = opts.delete(:desired_capabilities) { Remote::Capabilities.internet_explorer }
30
- port = opts.delete(:port) { Service::DEFAULT_PORT }
31
- http_client = opts.delete(:http_client)
32
- ignore_mode = opts.delete(:introduce_flakiness_by_ignoring_security_domains)
33
- native_events = opts.delete(:native_events) != false
34
-
35
- @service = Service.new(IE.driver_path, port, *extract_service_args(opts))
36
-
37
- unless opts.empty?
38
- raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
39
- end
40
-
29
+ port = opts.delete(:port) || Service::DEFAULT_PORT
30
+ service_args = opts.delete(:service_args) || {}
31
+ service_args = match_legacy(opts, service_args)
32
+ @service = Service.new(IE.driver_path, port, *extract_service_args(service_args))
41
33
  @service.start
34
+ opts[:url] = @service.uri
42
35
 
43
- caps['ignoreProtectedModeSettings'] = true if ignore_mode
44
- caps['nativeEvents'] = native_events
36
+ caps = opts[:desired_capabilities] ||= Remote::Capabilities.internet_explorer
37
+ caps[:ignore_protected_mode_settings] = true if opts.delete(:introduce_flakiness_by_ignoring_security_domains)
38
+ caps[:native_events] = opts.delete(:native_events) != false
45
39
 
46
- remote_opts = {
47
- url: @service.uri,
48
- desired_capabilities: caps
49
- }
50
- remote_opts[:http_client] = http_client if http_client
51
-
52
- super(remote_opts)
40
+ super(opts)
53
41
  end
54
42
 
55
43
  def browser
@@ -68,13 +56,20 @@ module Selenium
68
56
 
69
57
  private
70
58
 
71
- def extract_service_args(opts)
72
- args = []
73
- args << "--log-level=#{opts.delete(:log_level).to_s.upcase}" if opts[:log_level]
74
- args << "--log-file=#{opts.delete(:log_file)}" if opts[:log_file]
75
- args << "--implementation=#{opts.delete(:implementation).to_s.upcase}" if opts[:implementation]
59
+ def match_legacy(opts, args)
60
+ args[:log_level] = opts.delete(:log_level) if opts.key?(:log_level)
61
+ args[:log_file] = opts.delete(:log_file) if opts.key?(:log_file)
62
+ args[:implementation] = opts.delete(:implementation) if opts.key?(:implementation)
76
63
  args
77
64
  end
65
+
66
+ def extract_service_args(args)
67
+ service_args = []
68
+ service_args << "--log-level=#{args.delete(:log_level).to_s.upcase}" if args.key?(:log_level)
69
+ service_args << "--log-file=#{args.delete(:log_file)}" if args.key?(:log_file)
70
+ service_args << "--implementation=#{args.delete(:implementation).to_s.upcase}" if args.key?(:implementation)
71
+ service_args
72
+ end
78
73
  end # Bridge
79
74
  end # IE
80
75
  end # WebDriver