One Click vs Two Clicks - protractor

Scenario:
Testing web application using Protractor
Element needs to be clicked on to open another page
Designed the test to have one click on the element
Issue:
Sometimes elements needs one click and the test passes but if I run it again the same element needs double clicks
This is causing my test to fails randomly
I verified this by changing the command to have a double click in protractor and it passed.
This is causing inconsistency as I don't know when the element needs one or double clicks.
Any Suggestion is appreciated?

You may just need to put the element into focus explicitly via mouseMove() and then issue a click() action:
browser.actions().mouseMove(elm).click().perform();

Inconsistency might be because of element is not yet ready to click. So you need to wait until element become clickable and click it. Below code will help you in achieving consistency.
Code Snippet:
var EC = protractor.ExpectedConditions;
var elementToBeClick=element(locator);
var timeOut=10000;
browser.wait(EC.elementToBeClickable(elementToBeClick), timeOut).
thenCatch(function () {
assert.fail(' target element is not clickable');
});
elementToBeClick.click();

you can use browser.executeScripts to inject native javascript code into the browser and click the required button. this will execute the click event on the required element that you pass into the function
try the below code,
var elementToBeClick=element(locator);
browser.executeScript("arguments[0].click()",elementToBeClick.getWebElement())

Related

Issue with setting AutomationElement value

I have an issue with setting value of AutomationElement by using method ValuePattern.SetValue().
Everything works just fine until some dialog appears. When the dialog appears the code execution got stuck. No exception is thrown. After the dialog is confirmed, the code exection continues. Bellow is a sample of the code:
BasePattern basePattern = null;
ValuePattern valuePattern = null;
AutomationElement elementA = Window.GetElement(SearchCriteria.ByText(propertyName));
object patternObjectA = null;
elementA.TryGetCurrentPattern(ValuePattern.Pattern, out patternObjectA);
basePattern = (BasePattern)patternObjectA;
valuePattern = (ValuePattern)patternObjectA;
valuePattern.SetValue(optionToSet);
// Window.GetElement() is a method from TestStack.White framework
// The code execution got stuck on the last line until the dialog is confirmed
Is there any other way to set AutomationElement value?
Is somehow possible to avoid of getting stuck by dialog?
I'll by grateful for any help.
Thanks advance.
It could be that this dialog is not supporting UI Automation correctly or that you simply target the wrong element.
To verify that you may use Inspect.exe from Microsoft or similiar tools.
If it works, check if you really target the correct component with your code again.
If it does not work and:
if you are able to change the application
you can change the so called AutomationPeer of the UI component - here is a link for more infos
Or simply use another UI component that supports UI Automation correctly.
if you are not able to change the application, and also do not need to run in background, parallel, etc.. you might just focus the component (call setFocus() onto the AutomationElement, or expand it (via IsExpandCollapsePatternAvailable or simulated MouseClick onto the components coordinates)) and then use the SendKeys.SendWait("test") method.
EDIT: There is one more thing you should have a look at, and I wonder why I didn't mentioned it in the first place: Register to UI Automation Events
For example you could register a callback for the Structure change event type, and check if the dialog you talk about appeared.
If so --> click the confirmed button of the dialog.
Probably you will have to synchronize your execution, so that every further action in the UI Automation script waits until the registered callback got executed and the confirmed button got clicked.

Click button is not working in protractor

I am new to angular world. I am in process of automating the angular 2
application but I am having hard time to click a button.
Options tried:
I used various selectors like xpath, CSS, buttonText but none of them is working, s/m throws a timeout message or unable to find a selector.
When I try to print the element in console it is displaying as object object.
Do I need to return the value in format of string and then attempt to click?
Or
Do I need to add any require plug in from NPM ? Please let me know
script snippet:
var resubmit=element.all(by.xpath("//BUTTON[#_ngcontent=''][text()='resubmit']")).get('0');
console.log("return"+resubmit);
resubmit.click();
Wait untill element is become clickable and then click. You do it by following:
EC=protractor.ExpectedConditions;
var resubmit=element.all(by.buttonText('resubmit')).get('0');
browser.wait(EC.elementToBeClickable(resubmit), 15000,'Not Clickable'));
resubmit.click();

Google Closure add onclick to button after adding this button with custom editor plugin

I am making a custom plugin for the editor provided by Google Closure. The plugin makes it able to add a button.
I am having problems by setting an onclick on the button, the other values are nicely set.
button.innerHTML = event.label;
button.className = event.initialClass;
var extraClasses = event.extraClasses;
if (extraClasses)
{
button.className += ' ' + extraClasses
}
button.onclick = function() { event.onclick };
Does anyone know what I am doing wrong and how I can fix this?
After creating a button it is added to the editors SeamlessField. A second problem that I currently have is that after creating the button, my pointer is inside the button and I can't seem to get it out of there.
I've got the follow piece of code for handling this at the moment. The var button is the created button. button contains: <button class="orange">test</button>
// We want to insert the button in place of the user's selection.
// So we restore it first, and then use it for insertion.
this.restoreOriginalSelection();
var range = this.fieldObject.getRange();
button = range.replaceContentsWithNode(button);
// Done making changes, notify the editor.
this.fieldObject.dispatchChange();
// Put the user's selection right after the newly inserted button.
goog.editor.range.placeCursorNextTo(button, false);
// Dispatch selection change event because we just moved the selection.
this.fieldObject.dispatchSelectionChangeEvent();
Any ideas about how I could fix this second problem aswell?
For the first, it does not look like you have begun using Google Closure event code. Wiring up the button to the 'click' event in Google Closure would be as follows:
goog.events.listen(button, goog.events.EventType.CLICK, event.onclick)
You should also be investigating the goog.dom and goog.dom.classes namespaces if you'd like to use Google Closure's wrappers around standard CSS class and text DOM manipulation.
For the second, were you testing in Chrome? If so, you might have ran into a range issue in Webkit, documented within the Closure code itself:
https://code.google.com/p/closure-library/source/browse/closure/goog/editor/range.js#174
I have gotten around this in the past by inserting an empty <span> element as a sibling after the offending element (the button, in your case), and placing the cursor next to the <span> instead. However, there's nothing stopping the user from moving the cursor back inside your button. You'll have to add more logic to prevent a user from placing the cursor within the button's text.

How to prevent a button added by a userscript [GreaseMonkey/TamperMonkey] from submitting a form

Let me start off by saying that the code in question is part of a UserScript and, as such, normal DOM rules and Javascript methods do not work.
Here is the situation:
I have written a UserScript that interacts with an online chat site. I have a number of button that are generated within the user script. Some of these buttons are located inside of a form, while many of them are not.
Elements added through GreaseMonkey live in two worlds -- they live on the page DOM and they live in the slightly elevated world of UserScripts, which mean that these lines:
event.preventDefault = true;
event.stopPropagation = true;
prevent the rest of the UserScript actions from running, but it does not stop the button from causing a form submit.
As a work around, I am building span elements instead of a button. This works, but it really breaks the visual layout of the chat room.
Does anyone know a way to prevent elements added by UserScripts to prevent form submissions? Failing that, I'll dream that someone knows how to make a span look like a native button.
Edit: I have a solution which seems to be working -- but I haven't fully tested it under every UserScript environment:
// Yes, yes, poorly named but it was a SPAN
// userWindow is an alias for unsafeWindow.
// (Used to run under a userScript environment for IE and I had to emulate a lot)
var span = document.createElement("input");
span.value = text;
span.type = "button";
span.className = "cpbutton";
// Add it to the body just long enough to set up a page-level, DOM0 event handler
var body = userWindow.document.getElementsByTagName("body")[0];
var tname = "IAmTheVeryModelOfAModernMajorGeneral";
span.id = tname;
body.appendChild(span);
userWindow.document.getElementById(tname).onclick = function() {return false;};
body.removeChild(span);
span.id = "";
See the W3C spec for <button>.
By default, a <button> element acts as a submit button inside a form. This means that event.preventDefault() (the correct usage, BTW), on the click handler, may not be enough to stop the form submit.
In that case you could intercept the form's submit event too BUT, the smart thing to do is to use the type attribute to tell the browser not to treat the button as a submit button.
EG:
<button type="button">Your button markup</button>
when you say
to prevent elements added by UserScripts to prevent form submissions
i'm not sure if you want to allow or prevent submiting the form...
anyway, here is a link and a div disguised as a button: http://jsfiddle.net/RASG/PvhUb/
and if you post some of your code, i can help you with your script.

WWW::Selenium to capture component refresh

I am writing a perl script using WWW::Selenium module to automate a website.
I am not at all a web development guy and have no idea about web technologies.
Let me try to explain the issue in layman terms.
I am dealing with a webpage, which has an order form with a button.
When I click the button, there is no page submit, but the button label changes.
Say for eg, the button goes through these changes when clicked multiple times.
Get Quote --> Order --> Confirm Order
Each time I click the button, there is no page refresh, but the button label keeps changing as above.
The id of the button is the same throughout, only the class changes.
How can I do this in WWW::Selenium?
Presently I am using wait_for_page_to_load(5000) after each click.
But the click is not having any effect on the label and I get error that timed out after 5000s.
Should I be using some other function to wait?
You could do something like this
$sel->wait_for_text_present_ok("Your text","time to wait","The message to display if this fails");
and an example below-
$sel->wait_for_text_present_ok("Order Confirmed","9000","The order was successfully placed");
Seems like you could use
$class = $sel->get_attribute($attribute_locator)
where the $attribute_locator is the button#class with button being the element locator that you clicked. Check if $class is the class you expect.