Skip to content

Commit ea9345e

Browse files
committed
Added access to driver's Implicit timer and changed gecko's capabilities schema from depricated to modern
1 parent 2b69072 commit ea9345e

17 files changed

Lines changed: 257 additions & 126 deletions

Selenium.Tests/Internals/BaseBrowsers.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,16 @@ private WebDriver GetBrowserWithDriverStartedRemotely(Browser browser) {
8484
break;
8585
default: throw new Exception("Browser not supported: " + browser.ToString());
8686
}
87+
try {
8788
driver_process = Process.Start(p_info);
8889
NUnit.Framework.Assert.False( driver_process.HasExited, "Driver process cannot start: " + browser.ToString() );
8990
WebDriver s = new Selenium.WebDriver();
9091
s.StartRemotely( "http://localhost:4444/", browser.ToString().ToLower() );
9192
return s;
93+
} catch( Exception e ) {
94+
NUnit.Framework.Assert.Fail( "Thrown exception: " + e.Message );
95+
}
96+
return null;
9297
}
9398
}
9499
}

Selenium.Tests/TS_Scraping.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace Selenium.Tests {
77

88
[TestFixture(Browser.Firefox)]
9-
[TestFixture(Browser.Gecko)]
9+
[TestFixture(Browser.Gecko, Category = "InFocus")]
1010
[TestFixture(Browser.Chrome)]
1111
[TestFixture(Browser.Edge)]
1212
/*
@@ -36,6 +36,23 @@ public void ShouldScrapTextFromElements() {
3636
var data = elements.Text();
3737
A.AreEqual(data[0], "Table Heading 1");
3838
}
39+
40+
[TestCase]
41+
// [IgnoreFixture(Browser.Gecko, "Not supported")]
42+
public void ShouldGetBrowserLog() {
43+
driver.Get("/notexisting.html");
44+
Logs l = driver.Manage.Logs;
45+
List sl = l.Browser;
46+
A.IsNotNull( sl );
47+
}
48+
[TestCase]
49+
[IgnoreFixture(Browser.Gecko, "Not supported")]
50+
public void ShouldGetDriverLog() {
51+
driver.Get("/notexisting.html");
52+
Logs l = driver.Manage.Logs;
53+
List sl = l.Driver;
54+
A.IsNotNull( sl );
55+
}
3956
}
4057

4158
}

Selenium.Tests/TS_SearchContext.cs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,23 +138,45 @@ public void ShouldFindElementsByAny() {
138138
A.AreEqual(3, elts.Count);
139139
}
140140

141+
private void AddNewElementAfter( int delay ) {
142+
driver.ExecuteScript(@"setTimeout(function(){
143+
var e = document.createElement('div');
144+
e.id = 'id-append';
145+
e.innerHTML = 'DivAppend';
146+
document.body.appendChild(e);
147+
}, " + delay + ");");
148+
}
149+
141150
[TestCase]
142-
public void ShouldFindWithImplicitWait() {
143-
driver.ExecuteScript(@"
144-
setTimeout(function(){
145-
var e = document.createElement('div');
146-
e.id = 'id-append';
147-
e.innerHTML = 'DivAppend';
148-
document.body.appendChild(e);
149-
}, 100);
150-
");
151+
public void ShouldFindWithExplicitWait() {
152+
AddNewElementAfter( 200 );
151153
var ele = driver.FindElementById("id-append", 1500, true);
152154
}
153155

156+
[TestCase]
157+
public void ShouldFindWithImplicitWait() {
158+
AddNewElementAfter( 200 );
159+
var ele = driver.FindElementById("id-append");
160+
A.IsNotNull(ele);
161+
}
162+
163+
[TestCase]
164+
[IgnoreFixture(Browser.Gecko, "Implicit timeout is always 0 and cannot be changed")]
165+
public void ShouldFindWithDriverImplicit() {
166+
const int implicit_timeout = 500;
167+
driver.Timeouts.Implicit = implicit_timeout;
168+
if( Fixture.Equals( Browser.Firefox ) )
169+
A.Ignore( "Timeout can be only set but not get" );
170+
else
171+
A.AreEqual( implicit_timeout, driver.Timeouts.Implicit, "Cannot set the implicit timeout to the driver" );
172+
AddNewElementAfter( 200 );
173+
var ele = driver.FindElementById("id-append", 1, true);
174+
}
175+
154176
[TestCase]
155177
[ExpectedException(typeof(Selenium.Errors.NoSuchElementError))]
156178
public void ShouldNotFind() {
157-
var ele = driver.FindElementById("id-append", 5000, true);
179+
var ele = driver.FindElementById("id-missing", 5000, true);
158180
}
159181

160182
[TestCase]
@@ -178,5 +200,4 @@ public void ShouldGetThroughShadow() {
178200
A.Throws<SeleniumError>( () => sr.FindElementByXPath(".//span") ); // apparently not supported
179201
}
180202
}
181-
182203
}

Selenium.Tests/TS_Windows.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace Selenium.Tests {
99

1010
[TestFixture(Browser.Firefox)]
11-
[TestFixture(Browser.Gecko, Category = "InFocus")]
11+
[TestFixture(Browser.Gecko)]
1212
[TestFixture(Browser.Chrome)]
1313
[TestFixture(Browser.Edge)]
1414
/*

Selenium/ComInterfaces/_Timeouts.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ namespace Selenium.ComInterfaces {
99
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
1010
public interface _Timeouts {
1111

12-
[DispId(476), Description("Amount of time that Selenium will wait for waiting commands to complete")]
12+
[DispId(476), Description("Default amount of time that Selenium waits for search and wait operations.")]
1313
int ImplicitWait { get; set; }
1414

15+
[DispId(477), Description("Amount of time the driver waits when locating an element.")]
16+
int Implicit { get; set; }
17+
1518
[DispId(459), Description("Amount of time the driver should wait while loading a page before throwing an exception.")]
1619
int PageLoad { get; set; }
1720

Selenium/Common/Capabilities.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ public class Capabilities : Dictionary, ComInterfaces._Dictionary {
1111
const string KEY_BROWSER_NAME = "browserName";
1212
const string KEY_BROWSER_VERSION = "browserVersion";
1313
const string KEY_PLATFORM = "platform";
14+
const string KEY_PLATFORM_NAME = "platformName";
1415
const string KEY_NATIVE_EVENTS = "nativeEvents";
15-
const string KEY_ACCEPT_SSL_CERTIFICATES = "acceptSslCerts";
16+
const string KEY_ACCEPT_SSL_CERTS = "acceptSslCerts";
17+
const string KEY_ACCEPT_INSECURE_CERTS = "acceptInsecureCerts";
1618
const string KEY_ALERT_BEHAVIOUR = "unexpectedAlertBehaviour";
1719
const string KEY_PAGE_LOAD_STRATEGY = "pageLoadStrategy";
1820

1921
public Capabilities(){
2022
base.Add(KEY_PAGE_LOAD_STRATEGY, "normal");
21-
base.Add(KEY_ALERT_BEHAVIOUR, "ignore");
2223
}
2324

2425
public new object this[string key] {
@@ -64,10 +65,13 @@ public string BrowserVersion {
6465
/// </summary>
6566
public string Platform {
6667
get {
67-
return base.GetValue(KEY_PLATFORM, "ANY");
68+
return base.GetValue(WebDriver.LEGACY ? KEY_PLATFORM : KEY_PLATFORM_NAME, "ANY");
6869
}
6970
set {
70-
base[KEY_PLATFORM] = string.IsNullOrEmpty(value) ? "ANY" : value;
71+
if( WebDriver.LEGACY )
72+
base[KEY_PLATFORM] = string.IsNullOrEmpty(value) ? "ANY" : value;
73+
else
74+
base[KEY_PLATFORM_NAME] = string.IsNullOrEmpty(value) ? "windows" : value;
7175
}
7276
}
7377

@@ -88,22 +92,23 @@ public bool EnableNativeEvents {
8892
/// </summary>
8993
public bool AcceptUntrustedCertificates {
9094
get {
91-
return base.GetValue(KEY_ACCEPT_SSL_CERTIFICATES, false);
95+
return base.GetValue(WebDriver.LEGACY ? KEY_ACCEPT_SSL_CERTS : KEY_ACCEPT_INSECURE_CERTS, false);
9296
}
9397
set {
94-
base[KEY_ACCEPT_SSL_CERTIFICATES] = value;
98+
base[WebDriver.LEGACY ? KEY_ACCEPT_SSL_CERTS : KEY_ACCEPT_INSECURE_CERTS] = value;
9599
}
96100
}
97101

98102
/// <summary>
99-
/// Unexpected alert behaviour
103+
/// Unexpected alert behaviour. Legacy only
100104
/// </summary>
101105
public string UnexpectedAlertBehaviour {
102106
get {
103107
return base.GetValue(KEY_ALERT_BEHAVIOUR, string.Empty);
104108
}
105109
set {
106-
base[KEY_ALERT_BEHAVIOUR] = value;
110+
if( WebDriver.LEGACY )
111+
base[KEY_ALERT_BEHAVIOUR] = value;
107112
}
108113
}
109114

Selenium/Common/SearchContext.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public void WaitNotElement(By by, int timeout = -1) {
4343
/// </summary>
4444
/// <param name="strategy">The mechanism by which to find the elements.</param>
4545
/// <param name="value">The value to use to search for the elements.</param>
46-
/// <param name="timeout">Optional timeout in milliseconds</param>
46+
/// <param name="timeout">Optional timeout in milliseconds. When omitted the Timeouts.ImplicitWait value will be used</param>
4747
/// <param name="raise"></param>
4848
/// <returns>WebElement</returns>
4949
public WebElement FindElementBy(Strategy strategy, string value, int timeout = -1, bool raise = true) {
@@ -313,8 +313,7 @@ private WebElement FindFirstElement(Strategy strategy, string value, int timeout
313313
if (timeout == 0)
314314
throw;
315315
if( timeout == -1 ) timeout = session.timeouts.timeout_implicitwait;
316-
int time_chunk = timeout / 10;
317-
if( time_chunk < 50 ) time_chunk = 50;
316+
int time_chunk = SysWaiter.GetTimeChunk( timeout );
318317
var endTime = session.GetEndTime(timeout);
319318
while (true) {
320319
SysWaiter.Wait( time_chunk );

Selenium/Common/Timeouts.cs

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,40 @@
1-
using Selenium.Core;
1+
using System;
2+
using Selenium.Core;
23
using System.ComponentModel;
34
using System.Runtime.InteropServices;
45

56
namespace Selenium {
67

78
/// <summary>
8-
/// Timeouts object
9+
/// Timeouts used in in waiting
910
/// </summary>
1011
/// <example>
11-
/// Sets the implicit timout to 1 second
12+
/// Sets the deault operational time out to 1 second:
1213
/// <code lang="vb">
1314
/// driver.Timeouts.ImplicitWait = 1000
1415
/// </code>
16+
/// Tells the driver process to set its element location timeout to 1 second:
17+
/// <code lang="vb">
18+
/// driver.Timeouts.Implicit = 1000
19+
/// </code>
1520
/// </example>
1621
[ProgId("Selenium.Timeouts")]
1722
[Guid("0277FC34-FD1B-4616-BB19-44A424DB3F50")]
1823
[Description("Timeouts management")]
1924
[ComVisible(true), ClassInterface(ClassInterfaceType.None)]
2025
public class Timeouts : ComInterfaces._Timeouts {
26+
private const String ENDPOINT = "/timeouts";
2127

22-
private static void SendTimeoutScript(RemoteSession session, int timeout) {
23-
session.Send(RequestMethod.POST, "/timeouts", "type", "script", "ms", timeout);
28+
internal static void SendTimeoutScript(RemoteSession session, int timeout) {
29+
session.Send(RequestMethod.POST, ENDPOINT, "type", "script", "ms", timeout);
2430
}
2531

26-
private static void SendTimeoutPageLoad(RemoteSession session, int timeout) {
27-
session.Send(RequestMethod.POST, "/timeouts", "type", "page load", "ms", timeout);
32+
internal static void SendTimeoutPageLoad(RemoteSession session, int timeout) {
33+
session.Send(RequestMethod.POST, ENDPOINT, "type", "page load", "ms", timeout);
2834
}
2935

30-
private static void SendTimeoutImplicit(RemoteSession session, int timeout) {
31-
session.Send(RequestMethod.POST, "/timeouts", "type", "implicit", "ms", timeout);
36+
internal static void SendTimeoutImplicit(RemoteSession session, int timeout) {
37+
session.Send(RequestMethod.POST, ENDPOINT, "type", "implicit", "ms", timeout);
3238
}
3339

3440

@@ -42,6 +48,12 @@ private static void SendTimeoutImplicit(RemoteSession session, int timeout) {
4248
/// <summary>
4349
/// Amount of time that Selenium will wait for commands to complete. Default is 3000ms
4450
/// </summary>
51+
/// <remarks>
52+
/// This timeout is not linked to the driver process
53+
/// <see href="https://w3c.github.io/webdriver/#timeouts">implicit timeout</see>.
54+
/// It just a SeleniumBasic's default time for an element search operation would continue repeating a search requests
55+
/// until the timeout is reached.
56+
/// </remarks>
4557
/// <remarks>Default is 3000ms</remarks>
4658
public int ImplicitWait {
4759
get {
@@ -53,12 +65,37 @@ public int ImplicitWait {
5365
}
5466
}
5567

68+
/// <summary>
69+
/// Amount of time the driver process should wait to complete when locating an element.
70+
/// </summary>
71+
/// <remarks>
72+
/// Default is 0ms. See <see href="https://w3c.github.io/webdriver/#timeouts">implicit timeout</see>
73+
/// </remarks>
74+
public int Implicit {
75+
get {
76+
try {
77+
Dictionary dict = (Dictionary)_session.Send(RequestMethod.GET, ENDPOINT);
78+
if( dict != null )
79+
return Convert.ToInt32(dict["implicit"]);
80+
} catch { }
81+
return -1;
82+
}
83+
set {
84+
if (_session != null)
85+
SendTimeoutImplicit(_session, value);
86+
}
87+
}
88+
5689
/// <summary>
5790
/// Amount of time the driver should wait while loading a page before throwing an exception.
5891
/// </summary>
5992
/// <remarks>Default is 60000ms</remarks>
6093
public int PageLoad {
6194
get {
95+
Dictionary dict = (Dictionary)_session.Send(RequestMethod.GET, ENDPOINT);
96+
if( dict != null ) {
97+
timeout_pageload = Convert.ToInt32(dict["pageLoad"]);
98+
}
6299
return timeout_pageload;
63100
}
64101
set {
@@ -75,6 +112,10 @@ public int PageLoad {
75112
/// <remarks>Default is 15000ms</remarks>
76113
public int Script {
77114
get {
115+
Dictionary dict = (Dictionary)_session.Send(RequestMethod.GET, ENDPOINT);
116+
if( dict != null ) {
117+
timeout_script = Convert.ToInt32(dict["script"]);
118+
}
78119
return timeout_script;
79120
}
80121
set {
@@ -102,7 +143,7 @@ public int Server {
102143
internal void SetSession(RemoteSession session) {
103144
_session = session;
104145
SendTimeoutPageLoad(_session, timeout_pageload);
105-
SendTimeoutScript(_session, timeout_pageload);
146+
SendTimeoutScript(_session, timeout_script);
106147
}
107148

108149
}

Selenium/Core/DriverService.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,13 @@ public void Start(string filename, bool hide = true) {
8585
string servicePath = Path.Combine(_library_dir, filename);
8686
if (!File.Exists(servicePath))
8787
throw new Errors.FileNotFoundError(servicePath);
88-
88+
#if DEBUG
89+
const bool noWindow = false;
90+
#else
91+
const bool noWindow = true;
92+
#endif
8993
//Start the process
90-
_process = ProcessExt.Start(servicePath, _arguments, null, env, true, true);
94+
_process = ProcessExt.Start(servicePath, _arguments, null, env, noWindow, true);
9195

9296
//Waits for the port to be listening
9397
if (!_endpoint.WaitForListening(10000, 150))

Selenium/Core/RemoteSession.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,21 @@ public string Id {
4141
/// <summary>
4242
/// Starts a new session.
4343
/// </summary>
44-
/// <param name="desired_capabilities">An object describing the session's desired capabilities.</param>
45-
/// <param name="requiredCapabilities">An object describing the session's required capabilities (Optional).</param>
46-
/// <returns>{object} An object describing the session's capabilities.</returns>
44+
/// <param name="desired_capabilities">An object with the session's desired capabilities.</param>
45+
/// <param name="requiredCapabilities">An object with the session's required capabilities (Optional).</param>
46+
/// <exception cref="SeleniumException">When session start failed</exception>
4747
public void Start(Dictionary desired_capabilities, Dictionary requiredCapabilities = null) {
4848
var param = new Dictionary();
49-
param.Add("desiredCapabilities", desired_capabilities);
50-
if (requiredCapabilities != null)
51-
param.Add("requiredCapabilities", requiredCapabilities);
49+
if( WebDriver.LEGACY ) {
50+
param.Add("desiredCapabilities", desired_capabilities);
51+
if (requiredCapabilities != null)
52+
param.Add("requiredCapabilities", requiredCapabilities);
53+
} else {
54+
// see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities#Legacy
55+
var capabilities = new Dictionary();
56+
capabilities.Add( "alwaysMatch", desired_capabilities );
57+
param.Add("capabilities", capabilities);
58+
}
5259

5360
var response = (Dictionary)server.Send(RequestMethod.POST, "/session", param);
5461
try {

0 commit comments

Comments
 (0)