I have this page where an angularjs modal-content popup, in there i fill up some fields and click save. After save is initiated, popup should dissapear an event should happen and so on.
My selenium test does all that perfectly except that when it clicks on the save button, popup dissapears but no event is triggered or saved so when i open up the window again everything is empty. I've tried stuff that i know with selenium and it still doesn't work. Can anyone help me out here?
This is the save button:
<button class="save-button" data-ng-click="onSettingsSave()" ng-hide="readOnlyMode || !canSave()">Save</button>
Stuff i've tried:
var saveButton = driver.FindElement(By.CssSelector("button.save-button"));
saveButton.Click();
var saveButton = driver.FindElement(By.XPath(saveXpath));
saveButton.SendKeys(Keys.Enter);
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].focus();",saveButton);
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].click();",saveButton );
Try force clicking the element using pure JS:
driver.execute_script("arguments[0].click();", yourElement)
You can't use $ as a shortcut for document.querySelector in a script like that.
driver.ExecuteScript("document.querySelector('#base_element_id div input').click()");
Also this probably won't trigger an onClick in react / angular
Like the OP I have tried everything I can think of to get Selenium to trigger client side javascript events. I've seen some posts across the web of people having partial success where it randomly works; in my case it never works.
Selenium does successfully trigger the browsers primary click action, be it checking a checkbox or pressing a button, but it does not trigger any attached client side javascript events.
Both the native element.Click() method in selenium, and the abstracted ExecuteScript with arguments method of clicking as suggested by #csaladenes have the same result.
The only solution I have found so far is to use pure JS through that same ExecuteScript method; basically avoid the overload with params selenium can embed.
driver.ExecuteScript("$('#base_element_id div input').click()");
In my case I am using the JQuery that is already on my page to make locating the element easier, but any form of truly pure JS should do the same thing.
EDIT:
After some additional testing, it turns out that my "fix" really did nothing. However, performing the same click more than once did cause the client side events to fire.
In my case I am checking a checkbox, so I needed to perform the click 3 times to leave it in the correct state and still have the client side events run.
This is very odd, and definitely needs some more work to figure out where the issue is at that makes this necessary.
Edit 2:
I think I have finally found a solution, and at least partial answer, that does not make me cringe.
It seems as though Selenium has an issue where sometimes it "loses" the focus of the browser. Considering how consistent and repeatable my issue is I don't think focus is the only problem in my case, however the solution works pretty well.
I was able to get the immediate parent of my checkbox, which was a div element, click that first to return focus to the page, then click the checkbox. After that sequence of events the client side events worked correctly.
Related
The reason i need to execute the event behind a a element is because i'm working on some kind of autologin, however one of the sites it has to work with is https://create.kahoot.it/#login?a=1&next= the problem is, their login uses an a element for the sign in button, however when i select that element and execute a .click on it it simply doesn't do the same thing as to what happens when a user clicks on it.
I hope someone could answer this question since i couldn't find anything close to this issue anywhere.
Also for the convenience of whoever helps, to select the element from the console you could use:
document.getElementById('sign-in').getElementsByTagName('a')[1];
The way to solve this issue has to be either javascript or JQuery, preferably just plain javascript.
Try this:
document.getElementsByClassName('btn register')[0].click();
This basically is selecting the anchor by its class name and fire click event manually.
UPDATE:
Alright I did some more research and it seems there is another way of triggering that click handler and it is to set href on the window:
var a = document.getElementsByClassName('btn register')[1];
window.location.href = a.href;
I've tried it and seems it is doing the job.
Using Chrome's developer tools I am trying to determine what jQuery function is hooking an input button on the page for debugging purposes. I usually just keep searching until I find it, but I figured I'd ask this time.
Is there a way to find a jQuery button hook for a specific button in Chrome? I've tried looking through the Event Listener Breakpoints, but can never seem to find the right thing to pause it.
Basically, I need to know what jQuery / Javascript is being executed after the button is clicked.
The hooks are implemented in the application like so:
$('.button_class').click(function (){
$('#button_id').click(function(){
etc...
try this :
$(yourbutton).data('events');
Depending on the number of events/timers on the page this doesn't always work. But you can try "pausing" before clicking the button you want to debug in the JavaScript debug window. That way the debugger will pause on the next line that executes. The thing that occasionally prevents you from using that is if there is a "hover" or mouse move/in/out event tied on an element you have to pass over to get to the button (including the button itself). In that case I just remove those events (if I can) until I get the one I want. The event listener breakpoints would be more ideal but they're sometimes difficult when using jQuery or another library, I've actually put in a feature request to the Chrome Dev Tools team to address this very issue. (allowing you to specify what files are "yours" and only "breaking" in those specific files)
good luck -ck
I understand that it's possible (and I have done it) to return javascript and jQuery code (which of course is javascript... hehe) when doing a jQuery ajax request and running it once it reaches the browser.
What I'm wondering is if I return data, let's say a form, that I present in a dialogcontainer. What should I delete myself once that container is closed by the user and what does jQuery understand by itself to delete.
My idea is to build a page that require very little page reloads and once a user clicks on a button I present them with a form or some other content fetched from the server. Alongside that content the javascript required by that content should also be retrieved. But if the dialog is closet I don't want tons of javascript to be left eating memory. Any way around that?
You could unbind the click event that does the ajax call. If nothing is going to change if they open the dialog again, then this should be fine. While you unbind it you could then change it more a toggle type of thing (Show/Hide), since the javascript and HTML should already be set now.
But it really depends on what you are trying to do. The ajax call will only happen once they click it. It's not going to continually refresh unless you want to. So there should be nothing in the background running except for binding events like click, which is ok.
When I use AJAX for part of my page, such as a commentbox, in the reloaded box no JavaScript works. e.g. like cutetime or whatever. So I guess I have to reload the cutetime command (in every reload of the commentbox)
It works, but I think I have the cutetime command twice. If I have a confirm box or anything other, I get the confirm box or the add command twice.
I'll try to describe it in one sentence:
I need a way to get JavaScript working in a reloaded AJAX-Box.
P.S.: I think there is a very easy way because everybody uses it :)
If you replace an element anything attached to it is lost.
When using jQuery, you can avoid this issue by using live events. However, this doesn't work for plugins where you don't attach events. In that case you need to call whatever function enables something on your element again when replacing it.
I have a problem running Selenium IDE over one of my AJAX pages. There is a HTML button with a javascript onclick submit that causes a new form element to appear once the button is clicked. The button also only appears through AJAX after a select value has been selected on a previously displayed drop down.
Selenium sees the button appear and thinks it clicks it, but the click doesn't actually work.
I temporarily do not have access to the source code for reasons I won't get into. I know I'm probably being a bit vague here... I'll try to post more specifics when I can.
Cheers
EDIT: Just to clarify, I'm using the waitForVisible command on the button, which passes, and then the click, which also passes, but then it gets stuck on the next element which is making a selection from a drop down box. Selenium thinks it's doing this but it's not :(
Sometimes, depending on how the things are triggered in a page, selenium's click doesn't work.
This could be because the real onClick is later assigned with javascript somewhere else (even if the html tells you it has an "onClick" action.
Try replacing the click action with mouseDown and mouseUp one after the other using your locator as the parameter:
<tr>
<td>mouseDown</td>
<td>button_id</td>
<td></td>
</tr>
<tr>
<td>mouseUp</td>
<td>button_id</td>
<td></td>
</tr>
good luck!
I tried a lot of ways to do that in IE8 64bit and Windows 7. I've found that works perfect the method MouseDownAt and MouseUpAt. For example, I used the next code:
mouseDownAt(locator, "10,10");
mouseUpAt(locator, "10,10");
If the click of the button is simply not being recorded you will have to go into the code to manually write that step in while specifying the correct XPath expression or DOM path. Selenium could be auto generating an incorrect DOM path, but the only way to be sure is to look at the code.
The most probable answer is a timing issue. Selenium tends to fire steps faster than the DOM can render changes, and that causes errors. You might want to try specifying a two second pause directly between the generation of the button and the clicking of the button.
If the problem is something different you will have to be more specific.