The error is :
Exception in thread "main"
org.openqa.selenium.ElementNotInteractableException: Element is not reachable by keyboard
The code is:
System.setProperty("webdriver.gecko.driver","//Users//rozali//Documents//Selenium//geckodriver");
WebDriver driver = new FirefoxDriver();
driver.get("http://www.facebook.com");
driver.manage().window().maximize();
//entering first name
driver.findElement(By.id("u_0_b")).click();
driver.findElement(By.id("u_0_b")).sendKeys("testing it ");
//DOB
Select sel1 = new Select(driver.findElement(By.xpath(".//*[#id='month']")));
sel1.selectByIndex(4);
Select sel2 = new Select(driver.findElement(By.xpath(".//*[#id='day']")));
sel2.selectByValue("6");
Select sel3 = new Select(driver.findElement(By.xpath(".//*[#id='year']")));
sel3.selectByValue("2013");
//clicking sign up
driver.findElement(By.id("u_0_t")).click();
ElementNotInteractableException: Element is not reachable by keyboard
Element is not reachable by keyboard in plain words means that the element can’t be reached using the keyboard, which means you won't even physically interact with it.
Reason
There can be multiple reasons behind the error Element is not reachable by keyboard which can be either of the following:
The element is hidden, as modern JavaScript-centric UI styles always keep the ugly raw HTML input field hidden. The hidden attribute could have been implemented through either of the following ways:
A temporary overlay of some other element over the desired element.
A permanent overlay of some other element over the desired element.
Presence of attributes e.g. class="ng-hide", style="display: none", etc
As per best practices while sending character sequence, you must not attempt to invoke click() or sendKeys() on any <p> or <div> tag; instead, invoke click() on the desired <input> tag following the Official locator strategies for the webdriver.
Solution
There are different approaches to address this issue.
Incase of temporary overlay, use WebDriverWait inconjunction with ExpectedConditions for the desired element to be visible/clickable as follows:
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.nsg-button"))).click();
Incase of permanent overlay, use executeScript() method from JavascriptExecutor interface as follows:
import org.openqa.selenium.JavascriptExecutor;
String inputText = "Rozmeen";
WebElement myElement = driver.findElement(By.id("u_0_b"));
String js = "arguments[0].setAttribute('value','"+inputText+"')"
((JavascriptExecutor) driver).executeScript(js, myElement);
You will find a detailed discussion in Using JS to enter text, but if I input text in one text box, the value already entered is getting deleted.
Incase presence of attributes e.g. class="ng-hide", style="display: none", etc., use executeScript() method from the JavascriptExecutor interface to edit and reset the style="display: none" attribute to style="display: block" as follows:
import org.openqa.selenium.JavascriptExecutor;
((JavascriptExecutor) driver).executeScript("document.getElementById('ID').style.display='block';");
You will find a detailed discussion in Can't fill in the Hidden text area element.
References
For input[type=file], should allow sendKeys even when display=none
Special-casing file upload controls in keyboard-interactability check
Element is not reachable by keyboard
Input field with display: none is not interactable at all?
This particular issue
If you look into the HTML of Facebook login page, the application contains React Native elements. So an element once represented with id as u_0_b in your system may not be represented by the same id as u_0_b in the next run on your system. Hence, we have to take the help of Dynamic Locator Strategy. You can use the following code block to perform your intended steps :
Code Block :
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.facebook.com");
driver.findElement(By.xpath("//input[#name='firstname' and contains(#class,'inputtext')]")).sendKeys("testing it ");
//DOB
Select sel1 = new Select(driver.findElement(By.xpath(".//*[#id='month']")));
sel1.selectByIndex(4);
Select sel2 = new Select(driver.findElement(By.xpath(".//*[#id='day']")));
sel2.selectByValue("6");
Select sel3 = new Select(driver.findElement(By.xpath(".//*[#id='year']")));
sel3.selectByValue("2013");
//clicking sign up
driver.findElement(By.xpath("//button[#name='websubmit' and contains(.,'Sign Up')]")).click();
Browser Client :
Update
Addressing the error:
org.openqa.selenium.ElementNotInteractableException: Element is not
reachable by keyboard
has become easier with the availability of Firefox capability moz:webdriverClick
moz:webdriverClick()
Through webdriverClick(), you can pass a boolean value to indicate which kind of interactability checks to run when performing a click or sending keys to an element. For Firefoxen prior to v58.0, some legacy code as imported from an older version of FirefoxDriver was in use. With the availability of Firefox v58, the interactability checks as required by the WebDriver specification are enabled by default. This means that geckodriver will additionally check if an element is obscured by another when clicking and if an element is focusable for sending keys. Because of this change in behaviour, we are aware that some extra errors could be returned. In most cases, the test in question might have to be updated so it conforms with the new checks.
To temporarily disable the WebDriver conformant checks, use false as value for this capability.
Note: This capability exists only temporarily, and it will be removed once the interactability checks have been stabilized.
You can try this code :
public class Rozmeen{
static WebDriver driver;
static WebDriverWait wait;
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.gecko.driver", "F:\\Automation\\geckodriver.exe");
driver = new FirefoxDriver();
driver.manage().window().maximize();
WebDriverWait wait = new WebDriverWait(driver, 40);
driver.get("http://www.facebook.com");
//entering first name
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("pagelet_bluebar"))));
driver.findElement(By.name("firstname")).sendKeys("testing it ");
//DOB
selectFromDropDown(driver.findElement(By.name("birthday_day")), "4");
selectFromDropDown(driver.findElement(By.name("birthday_month")), "Jun");
selectFromDropDown(driver.findElement(By.name("birthday_year")), "2013");
//clicking sign up
wait.until(ExpectedConditions.elementToBeClickable(driver.findElement(By.name("websubmit"))));
driver.findElement(By.name("websubmit")).click();
}
public static void selectFromDropDown(WebElement element , String Visibletext){
Select select = new Select(element);
select.selectByVisibleText(Visibletext);
}
}
try out this code and let me know the status.
In one of the use cases I had the same issue:
Exception in thread "main" org.openqa.selenium.ElementNotInteractableException: Element <div id="search"> is not reachable by keyboard
using id for identifying an element before sending keys. Something like:
driver.findElement(By.id("search")).sendKeys("...");
After testing I changed to CSS Selector and it solved the issue:
driver.findElement(By.cssSelector("#search > input:nth-child(2)")).sendKeys("...");
So, I highly recommend to use different methods to interact with the elements, because something else can save your time solving problems.
Sometimes it is also an issue by using name/id like this:
driver.findElement(By.name("phone")).sendKeys("99999999");
Instead of this, use Xpath. This solved the issue for me:
driver.findElement(By.xpath("//*[#id='load_form']/input")).sendKeys("Java");
I got a similar error on a button when the click() operation was performed:
org.openqa.selenium.ElementNotInteractableException Exception
As mentioned by DebanjanB in his answer, the element was not reachable by keyboard.
To solve this, I replaced click() with sendKeys(Keys.ENTER), and the button got clicked.
Related
The asp-items Razor "TagHelper" will add an <option> to a <select> for each value in the SelectList. I want to modify each of those children.
Specifically I want to disable some of them (i.e. add disabled="disabled").
Even more specifically I want to dynamically disable some of them; I'm using angular so I could ng-disabled="{dynamic_boolean_which_determines_disabled}". This means the option could be disabled at first, but after user makes a change, the option could be disabled (without page reload). Angular should take care of this; I think Angular and TagHelpers should work together in theory...
I expected:
I could somehow access an IEnumerable of the children <option> tags that would be created (i.e. one for each item in the SelectList), iterate the children tags, and SetAttribute("disabled") or SetAttribute("ng-disabled")...
I tried:
Creating my own TagHelper which targets the select[asp-items], and tries to GetChildContentAsync() and/or SetContent to reach an IEnumerable <option> tags and iterate them and process each, but I think this will only let me modify the entire InnerHtml as a string; feels hacky to do a String.replace, but I could do it if that's my only option? i.e. ChildrenContent.Replace("<option", "<option disabled=\"...\"")
Creating my own TagHelper which targets the option elements that are children of the select[asp-items], so I can individually process each. This works, but not on the dynamically-added <option> created by asp-items, it only works on "literal" <option> tags that I actually put into my cshtml markup.
I think this'll work but not ideal:
As I said above, I think I can get the result of TagHelper's dynamic asp-items <option></option> <option></option>, as a string, and do a string replace, but I prefer not to work with strings directly...
I suspect (I haven't tried it) that I could just do the work of asp-items myself; i.e. custom-items. But then I'm recreating the wheel by re-doing the work which asp-items could've done for me?
So I hadn't yet read the "AutoLinkHttpTagHelper" in the example which uses string replacement (specifically RegEx replace) to replace every occurrence of a URL, with an <a> pointed at that URL. The cases are slightly different*, but...
Anyway, here's my solution once I learned to stop worrying and love the string modification:
[HtmlTargetElement("select", Attributes = "asp-items")]
public class AspItemsNgDisabledTagHelper : SelectTagHelper
{
//Need it to process *after* the SelectTagHelper
public override int Order { get; } = int.MaxValue;
//https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring#ProcessAsync
public AspItemsNgDisabledTagHelper(IHtmlGenerator gen) : base(gen) {}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
//Notice I'm getting the PostContent;
//SelectTagHelper leaves its literal content (i.e. in your CSHTML, if there is any) alone ; that's Content
//it only **appends** new options specified; that's PostContent
//Makes sense, but I still wasn't expecting it
var generated_options = output.PostContent.GetContent();
//Note you do NOT need to extend SelectTagHelper as I've done here
//I only did it to take advantage of the asp-for property, to get its Name, so I could pass that to the angular function
var select_for = this.For.Name;
//The heart of the processing is a Regex.Replace, just like
//their example https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring#inspecting-and-retrieving-child-content
var ng_disabled_generated_options = Regex.Replace(
generated_options,
"<option value=\"(\\w+)\">",
$"<option value=\"$1\" ng-disabled=\"is_disabled('{select_for}', '$1')\">");
//Finally, you Set your modified Content
output.PostContent.SetHtmlContent(ng_disabled_generated_options);
}
}
Few learning opportunities:
Was thinking I'd find AspForTagHelper and AspItemsTagHelper, (angular background suggested that the corresponding attributes; asp-for and asp-items, would be separate "directives" aka TagHelper).
In fact, TagHelper "matching" focuses on the element name (unlike angular which can match element name... attribute... class... CSS selector)
Therefore I found what I was looking for in SelectTagHelper, which has For and Items as properties. Makes sense.
As I said above, I extend SelectTagHelper, but that's not necessary to answer my original question. It's only necessary if you want access to the this.For.Name as I've done, but there may even be a way around that (i.e. re-bind its own For property here?)
I got on a distraction thinking I would need to override the SelectTagHelper's behavior to achieve my goals; i.e. Object-Oriented Thinking. In fact, even if I did extend SelectTagHelper, that doesn't stop a separate instance of the base SelectTagHelper from matching and processing the element. In other words, element processing happens in a pipeline.
This explains why extending and calling base.Process(), will result in Select doing its job twice; once when your instance matches, and again when the base instance matched.
(I suppose could've prevented SelectTagHelper from matching by creating a new element name like <asp-items-select>? But, not necessary... I just avoid calling base.Process(). So unless that's a bad practice...)
*Different in this way:
They want to create a tag where none exists, whereas I want to add an attribute a tag which is already there; i.e. the <option>
Though the <option> "tag" is generated by the SelectTagHelper in its PostContent (was expecting to find it in Content), and I don't think tags-generated-in-strings-by-content-mods can be matched with their corresponding TagHelper -- so maybe we really are the same in that we're just dealing with plain old strings
Their "data" aka "model" is implied in the text itself; they find a URL and that URL string becomes a unit of meaning they use. In my case, there is an explicit class for Modeling; the SelectList (<select>) which consists of some SelectListItem (<option>) -- but that class doesn't help me either.
That class only gives me attributes like public bool Disabled (remember, this isn't sufficient for me because the value of disabled could change to true or false within browser; i.e. client-side only), and public SelectListGroup Group -- certainly nothing as nonstandard as ng-disabled, nor a "catch-all" property like Attributes which could let me put arbitrary attributes (ng-disabled or anything else) in there.
Nowadays, I am working on a java swing application using DJ NativeSwing as my embed browser to do something automatic work. The scenario of my application is that a user click start button and the embed browser auto click some position of the current page and then redirect to another one and then execute some other operations like click or something other. Now here is my solution. First, I will define a webbrowser class (extends JWebBrowser) and webbrowser listener class (implements WebBrowserListener), which represents a webbrowser and contains loadingProgressChanged, windowOpening and so on separately. Second, I define a thread class to do some logic computing and execute my browser operations as mentioned above by webbrowser.executeJavascript. At last, I add mouseListener for start and stop button to start or stop the task. When I open my application, the JFrame add the browser and its listener class. I click the start button, the browser works and will click the target position as I expected and then the page will redirect to another one. As we all know, js code can’t be executed until the page was loaded completely. So I set a global flag to check whether the page has loaded completely or not in loadingProgressChanged (code:if(e.getWebBrowser().getLoadingProgress() == 100)globalflag = true;) within webbrowser listener class. And in the thread class, I use code( while(globalflag == false){Thread.sleep(500);}) after first click to detect if the current page was loaded completely. However, when browser first click the target position and the page redirects successfully, I find that the current page has changed but blocked. After some debugging, I find it. In my thread class, browser will execute js code by webbrowser.executeJavascript("document.getElementById(‘target’).click();") to click the target position and then java code (while(globalflag == false){Thread.sleep(500);}) to detect if the current page was loaded completely and then execute some other java code. I find that the globalflag will never change and the current page’s loadingProgressChanged listener will never work because the java code (while(globalflag == false)). Because after I remove all java code after the first webbrowser.executeJavascript("document.getElementById(‘target’).click();"), the current page’s loadingProgressChanged listener works and the page was not blocked. With the DJ NativeSwing demo, I could execute my js in the loadingProgressChanged. However, I want to do a series of operations with my browser and also want to stop the task whenever need. So, I prefer to my solution for my demand rather than the provided one by demo. So, I wonder that after webbrowser.executeJavascript the DJ NativeSwing thread will wait my thread? And, in my software architecture, does anyone could have any suggestions? Thanks a lot. Any suggestion is appreciated!
PS.my application works fine with jdic-0.9.5, but it supports IE7 only.
I paste my code here to demonstrate my problem:
After I click the start button in JFrame, I will new a thread as follow
public class MyVisit implements Runnable{
private void doClick1(){
webbrowser.executeJavascript("document.getElementById('n').value='test'");
webbrowser.executeJavascript("document.getElementById('f').submit()");
}
public void run() {
globalFlag=false;
webbrowser.executeJavascript("document.getElementById(‘t’).click();") ;
while(!globalFlag){
Thread.sleep(500);
}
this.doClick1();
}
}
listener:
public class MyListener implements WebBrowserListener {
…
public void loadingProgressChanged(WebBrowserEvent e) {
if (e.getWebBrowser().getLoadingProgress() == 100) {
globalFlag=true;
}
}
}
DJ Native Swing enforces the Swing approach to threading: manipulate the components in the AWT Event Dispatch thread (a.k.a. UI thread). But also, do not block that thread, because listeners are triggered in that thread too.
So, you should not have a "while" loop in the UI thread, but should instead spawn a new thread. I hope your global variable is volatile, or AtomicBoolean or all accesses to it protected by synchronized block, otherwise you might have interesting threading side effects.
I am starting to learn Unity.
As I understand, We can write scripts(behaviors) in the form of C# files and apply them to each objects on the scene.
But how to write a script for the entire scene? I know this is a obvious question - there has to be a script for the entire scene so that all my objects "behave" in a synchronized way and it's gotta be pretty basic, but preliminary Google searches has not borne much fruit.
Can someone give me a quick guide?
Taking your "boxes" example comment I would do the following:
Create an empty gameobject, let's call it BoxesController...
Attach below BoxesController.cs script to it
In the editor inspector reference all boxes
BoxesController.cs
public class BoxesController: MonoBehaviour
{
public Transform box1, box2, box3;
void Update() {
// change boxes position
}
}
Now imagine you will need to have > 30 boxes in current scene... You will have a lot of work to reference each box. So you could change your script if you add a Tag to all boxes. Let's say you create a new tag inside Unity Tag Manager called "Box" and give it to all boxes.
You now can change BoxesController.cs script to the above and you will not have to reference all boxes in the Editor Inspector because they will be searched and referenced inside Start method.
BoxesController.cs
public class BoxesController: MonoBehaviour
{
public GameObject[] boxes;
void Start()
{
boxes = GameObject.FindGameObjectsWithTag("Box");
}
void Update() {
// change boxes position
foreach (GameObject go in boxes)
{
//get box name
string box_name = go.Name;
// get box transform property
Transform t = go.transform;
}
}
}
Please note that GameObject.FindGameObjectsWithTag is a heavy operation and that's why I did it in the Start method and saved the result to reuse it in Update method calls.
what you can do is create an empty GameObject and add a script to it and use one of the techniques described in the link to get access to the 3 boxes you want to move.
http://docs.unity3d.com/412/Documentation/ScriptReference/index.Accessing_Other_Game_Objects.html
In this case you probably want to use "1. Through inspector assignable references." which just means create a public Transform variable in the script, save, then in the Inspector drag the box in the slot that appeared in the script-component
edit: for further reading i'd suggest googling the term "Game Manager" in combination with "Singelton" and "Unity" :)
I have a basic question. I have developed a Python component that just prints the value of a simple property to the console screen and a waveform that just runs the component.
I'm trying to create a component control panel that displays the current property value (a string) and also allows me to change the value of the property. When I change the value of the property, I would like the value printed to the console window to change too. My understanding is that I need to bind the property to a text box on the control panel.
I attempted to follow the binding example in section 24.4.1 of the documentation (http://redhawksdr.github.io/Documentation/mainch24.html), by adding their bind code to the refresh() function that was automatically generated by the SCA Component Control Panel wizard. However, when I view the control panel, I get the error:
An internal error occurred during: "Refresh Component".
null argument: Validation realm cannot be null
I am fairly new to Java, but my guess is that I'm receiving the error because there was some problem when creating the local copy of the SCA component (variable named "component" in the code below).
Here is my control panel code:
public void createPartControl(final Composite main) {
main.setLayout(new GridLayout(2, false));
propValue = new Text(main, SWT.BORDER);
propValue.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
}
public void refresh() {
Job refreshJob = new Job("Refresh Component") {
#Override
protected IStatus run(IProgressMonitor monitor) {
// bind text box to component property value
final ScaComponent component = getInput();
EMFDataBindingContext context = new EMFDataBindingContext();
IObservableValue observable = SCAObservables.observeSimpleProperty(component,"someText");
context.bindValue(WidgetProperties.text().observeDelayed(5000, propValue),observable);
return Status.OK_STATUS;
}
};
refreshJob.setSystem(true);
refreshJob.schedule();
}
For reference, I am running REDHAWK version 1.8.2 on RHEL 5.8.
I believe the problem here is you are trying to create a binding from within a Job.
Creation of bindings should be done within the SWT thread. The error you are getting is indicating that was unable to acquire a realm to execute within. If this code is executed within the SWT thread it will correctly acquire the SWT realm.
Text propValue = new Text(main, SWT.BORDER);
EMFDataBindingContext context = new EMFDataBindingContext();
IObservableValue observable = SCAObservables.observeSimpleProperty(component, "simplePropId");
context.bindValue(WidgetProperties.text().observeDelayed(5000, propValue), observable);
Notice in the example how the bindings are immediately created. This ensures the bindings are within the correct realm.
Control panels will have the input model change occasionally. Therefore it may be necessary to create the bindings within the refresh or setInput methods. These methods are also called from the SWT thread.
Note you should free the old context before rebinding to the new model by using context.dispose and creating a new context.
For an example on how data bindings work checkout: http://www.vogella.com/articles/EclipseDataBinding/article.html
In my selenium webdriver code I'm trying to get my page to wait for it to load before it starts finding elements and driving them(entering text into username and password)
I tried using driver.waitforpagetoload(); but it returned this error
Error 1 'OpenQA.Selenium.IWebDriver' does not contain a definition for 'waitforpagetoload' and no extension method 'waitforpagetoload' accepting a first argument of type 'OpenQA.Selenium.IWebDriver' could be found (are you missing a using directive or an assembly reference?)
What type of reference to I need to add?
(coding in c#)
I found it was helpful to use Thread.Sleep(# of milliseconds), which allowed the pages to load before continuing onto the next element.
Example:
using System;
namespace SeleniumTests
{
[TestFixture]
public class FireFoxTests
{
[Test]
public void SomeTest()
{
some code;
Thread.Sleep(2000);
more code;
}
}
}
The error is because webdriver doesn't have a waitForPageToLoad function.
And you dont need it with webdriver because it will automatically block after every action, untill the page loads completely. More details here .. WebDriver FAQ
But you can have custom waits, like wait for Elements to appear on page using WebDriverWait.