WebDriver can generally be said to have a blocking API.Because it is an out-of-process library thatinstructs the browser what to do,and because the web platform has an intrinsically asynchronous nature,WebDriver does not track the active, real-time state of the DOM.This comes with some challenges that we will discuss here.
From experience,most intermittent issues that arise from use of Selenium and WebDriverare connected to race conditions that occur betweenthe browser and the user’s instructions.An example could be that the user instructs the browser to navigate to a page,then gets a no such element errorwhen trying to find an element.
Consider the following document:
The WebDriver instructions might look innocent enough:
NCR RealPOS Keyboards NCR offers a POS keyboard product line to complement each NCR POS terminal.The NCR RealPOS keyboard family features a variety of sizes, layouts and optional features to fit any environment. Whether you need a traditional EPOS keyboard layout, an alphanumeric style, or both, NCR has a keyboard to meet your needs. The NCR RealScan 7832 is a small, durable handheld scanner featuring a mechanical/magnetic laser scan engine. It is designed to offer a true laser scanner at the price of wand or CCD technology, for price-sensitive retail applications such as POS, receiving, and inventory control/ordering. Support & Downloads Get troubleshooting, maintenance and warranty information. Download software, drivers and brochures. We dedicate ourselves to provide every day the best service to our customers and partners, and today is no exception. CLICK HERE for latest news and for any assistance on inquiries, delivery, or support.
The issue here is that the defaultpage load strategyused in WebDriver listens for the document.readyState
to change to 'complete'
before returning from the call to navigate.Because the p
element isadded after the document has completed loading,this WebDriver script might be intermittent.It “might” be intermittent because no guarantees can be madeabout elements or events that trigger asynchronouslywithout explicitly waiting—or blocking—on those events.
Fortunately, the normal instruction set available onthe WebElement interface—suchas WebElement.click and WebElement.sendKeys—areguaranteed to be synchronous,in that the function calls will not return(or the callback will not trigger in callback-style languages)until the command has been completed in the browser.The advanced user interaction APIs,Keyboardand Mouse,are exceptions as they are explicitly intended as“do what I say” asynchronous commands.
Waiting is having the automated task executionelapse a certain amount of time before continuing with the next step.
To overcome the problem of race conditionsbetween the browser and your WebDriver script,most Selenium clients ship with a wait package.When employing a wait,you are using what is commonly referred toas an explicit wait.
Explicit wait
Explicit waits are available to Selenium clientsfor imperative, procedural languages.They allow your code to halt program execution,or freeze the thread,until the condition you pass it resolves.The condition is called with a certain frequencyuntil the timeout of the wait is elapsed.This means that for as long as the condition returns a falsy value,it will keep trying and waiting.
Since explicit waits allow you to wait for a condition to occur,they make a good fit for synchronising the state between the browser and its DOM,and your WebDriver script.
To remedy our buggy instruction set from earlier,we could employ a wait to have the findElement callwait until the dynamically added element from the scripthas been added to the DOM:
We pass in the condition as a function referencethat the wait will run repeatedly until its return value is truthy.A “truthful” return value is anything that evaluates to boolean truein the language at hand, such as a string, number, a boolean,an object (including a WebElement),or a populated (non-empty) sequence or list.That means an empty list evaluates to false.When the condition is truthful and the blocking wait is aborted,the return value from the condition becomes the return value of the wait.
With this knowledge,and because the wait utility ignores no such element errors by default,we can refactor our instructions to be more concise:
In that example, we pass in an anonymous function(but we could also define it explicitly as we did earlier so it may be reused).The first and only argument that is passed to our conditionis always a reference to our driver object, WebDriver.In a multi-threaded environment, you should be carefulto operate on the driver reference passed in to the conditionrather than the reference to the driver in the outer scope.
Because the wait will swallow no such element errorsthat are raised when the element is not found,the condition will retry until the element is found.Then it will take the return value, a WebElement,and pass it back through to our script.
If the condition fails,e.g. a truthful return value from the condition is never reached,the wait will throw/raise an error/exception called a timeout error.
Options
The wait condition can be customised to match your needs.Sometimes it is unnecessary to wait the full extent of the default timeout,as the penalty for not hitting a successful condition can be expensive.
The wait lets you pass in an argument to override the timeout:
Expected conditions
Because it is quite a common occurrenceto have to synchronise the DOM and your instructions,most clients also come with a set of predefined expected conditions.As might be obvious by the name,they are conditions that are predefined for frequent wait operations.
The conditions available in the different language bindings vary,but this is a non-exhaustive list of a few:
Ncr Keyboards Drivers
- alert is present
- element exists
- element is visible
- title contains
- title is
- element staleness
- visible text
You can refer to the API documentation for each client bindingto find an exhaustive list of expected conditions:
- Java’s org.openqa.selenium.support.ui.ExpectedConditions class
- Python’s selenium.webdriver.support.expected_conditions class
- .NET’s OpenQA.Selenium.Support.UI.ExpectedConditions type
Implicit wait
There is a second type of wait that is distinct fromexplicit wait called implicit wait.By implicitly waiting, WebDriver polls the DOMfor a certain duration when trying to find any element.This can be useful when certain elements on the webpageare not available immediately and need some time to load.
Implicit waiting for elements to appear is disabled by defaultand will need to be manually enabled on a per-session basis.Mixing explicit waits and implicit waitswill cause unintended consequences, namely waits sleeping for the maximumtime even if the element is available or condition is true.
Warning:Do not mix implicit and explicit waits.Doing so can cause unpredictable wait times.For example, setting an implicit wait of 10 secondsand an explicit wait of 15 secondscould cause a timeout to occur after 20 seconds.
An implicit wait is to tell WebDriver to poll the DOMfor a certain amount of time when trying to find an element or elementsif they are not immediately available.The default setting is 0, meaning disabled.Once set, the implicit wait is set for the life of the session.
FluentWait
FluentWait instance defines the maximum amount of time to wait for a condition,as well as the frequency with which to check the condition.
Users may configure the wait to ignore specific types of exceptions whilst waiting,such as NoSuchElementException
when searching for an element on the page.
The magnetic stripe reader driver sample demonstrates how to create a universal driver for a magnetic stripe reader and is intended to be used as a template for creating a new driver. The sample uses the User-Mode Driver Framework (UMDF) 2.0 and demonstrates basic functionality such as claiming the device for exclusive access. The sample driver can be compiled and deployed on x86, amd64, and ARM platforms.
Requirements
Windows 10
Microsoft Visual Studio (any version)
The Windows Software Development Kit (SDK) 10 is also required, but this is installed as part of Microsoft Visual Studio.
Note
The sample driver does not require any magnetic stripe reader hardware to function because it operates on a software device. If you have a hardware device you wish to use with the sample, you can still use the driver by adding the device's hardware ID to the INF file.
Download and extract the sample
The Windows driver samples are available on GitHub.
Download Windows-driver-samples-master.zip. This file contains all Windows Driver Kit (WDK) samples.
Extract Windows-driver-samples-master.zip to the location of your choice on your development machine. This location will be referred to as
<sample_root>
throughout the remainder of this article.
Open the driver solution in Visual Studio
In Windows Explorer, navigate to the
<sample_root>posdriversMagneticStripeReader
folder.Double-click the solution file, MagneticStripeReader.sln to open the solution with Visual Studio.
The project zip file was downloaded from the Internet so you may see a security warning when you open the solution. If you do, click OK to finish loading the project.
In Visual Studio, locate Solution Explorer. If this is not already open, select Solution Explorer from the View menu. In Solution Explorer, you can see the project and the source files it contains.
Build the sample using Visual Studio
Ncr Drivers
From the Standard toolbar in Visual Studio, select the Solution Platform that matches your operating system platform. For example, if you are using a 64-bit version of Windows, select x64.
Note
If targeting the ARM platform, you will need to use the configuration manager to add ARM to your list of targets.
Select Build Solution from the Build menu.
Install the driver
When built, the driver was signed with a test certification. In order to install the driver for testing, you need to change your boot configuration to allow drivers signed with a test certificate to load. To change the setting, open up an elevated command prompt and enter the command:
bcdedit.exe /set TESTSIGNING on
Reboot your machine.
Note
If test-signing had been enabled previously, a reboot is not necessary.
From an elevated command prompt, navigate to the folder where your project was built. If you created an x64 debug build, this folder will be
<project_root>x64DebugSampleMagneticStripeReaderDrv
.In that folder, you will see the following files:
File Description SampleMagneticStripeReaderDrv.dll The driver file. SampleMagneticStripeReaderDrv.inf An INF file that contains information needed to install the driver. samplemagneticstripereaderdrv.cat A signed catalog file, which serves as the signature for the entire package. Identify the path to the Device Console utility (devcon.exe) that matches your OS and driver platform. The default locations for the x64 version is
C:Program Files (x86)Windows Kits10Toolsx64
.Type the following command, replacing <devcon_path> with the path to the devcon.exe file that you located in the previous step.
'<devcon_path>devcon.exe' install SampleMagneticStripeReaderDrv.inf RootSampleMagneticStripeReaderDrv
You will see a Windows Security dialog informing you that the publisher of the driver can't be verified. This is because the driver was signed with a test certificate. Click Install this driver software anyway. In a moment, you will see confirmation that your driver was installed correctly.
If the Device Console utility wasn't able to install the driver, confirm that you were using the one that matches your current OS platform and the platform of the driver.
View the device in Device Manager
Open Device Manager. This can be done many ways, but if you're still in a command prompt then type
devmgmt
.In Device Manager, choose Devices by type from the View menu.
Your device is listed under the Samples node.