JQuery Change Event for InnerHTML - innerhtml

In my case i'm writing a Chrome Extension, I don't have access to the other JS that is happening on the page. So I need to make sure that whenever certain elements update their content I rerun a function from the extension.
Basically a Change event that can be triggered from innerHTML changing.

Since it's for a Chrome extension, might as well the standard DOM Mutation events.
Listen to DOMSubtreeModified on the document. Just tested on Chrome 5.0.375.99 and it is supported.
document.addEventListener('DOMSubtreeModified', myFunction);

Related

Vue preventing default router-link behaviour works in Chrome but not in Firefox

I have a component that has a router-link as a root tag. I want to prevent its default link behavior so it would fall back to the link if something is wrong with JS or it's disabled.
I made it work in Chrome with such event modifiers:
#click.native.capture.prevent
But it doesn't work in Firefox.
What am I missing?
Codesandbox
UPD: I found a workaround, but I'm still curios why this isn't working
It seems like Firefox treats multiple events on an element differently than Chrome which is why your code doesn't work as expected. I'm not exactly sure at this point, but it might be that Chrome works off all event listeners from the bottom up, whereas Firefox works from top down. This results in Chrome not firing the 1st event since the previous one (in this case the 2nd) uses prevent default, as you can see on the images below (that's just the event you added using #click.native.capture.prevent).
Chrome event handler:
Firefox event handler:
Since Vue Router adds a click event to a router-link on default you can solve this issue by either adding a wrapper to your child component (in this case the event won't get captured by the router-link since the wrapper prevents it)
<div>
<router-link to="/shop"> text link</router-link>
</div>
or by manually overwriting the event property.
<router-link to="/shop" event=""> text link</router-link>
You can see how it works using a wrapper here.

How to inject CSS into webkit?

On Linux I'm creating a webkit window which needs to display a certain URL.
I'm doing that like the following:
GtkWidget *main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
// Create a browser instance
WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
// Put the browser area into the main window
gtk_container_add(GTK_CONTAINER(main_window), GTK_WIDGET(webView));
// Load a web page into the browser instance
webkit_web_view_load_uri(webView, "http://example.com");
// Make sure that when the browser area becomes visible, it will get mouse
// and keyboard events
gtk_widget_grab_focus(GTK_WIDGET(webView));
// Show the result
gtk_window_set_default_size(GTK_WINDOW(main_window), 800, 600);
gtk_widget_show_all(main_window);
However, I need to inject some CSS into this to hide a certain checkbox.
How do I inject CSS into the DOM.
I see that I can get the dom like
WebKitDOMDocument *dom = webkit_web_view_get_dom_document(webView);
But from here I can't see how to inject the CSS.
It sounds like the webkit_web_view_run_javascript() answer was a good solution to your specific problem, since you only needed to hide one checkbox.
To answer the general problem of how to inject arbitrary CSS: if you're using a recent version of WebKitGTK+, create a WebKitUserContentManager, call webkit_user_content_manager_add_stylesheet(), and then pass the WebKitUserContentManager when creating your WebKitWebView, either using webkit_web_view_new_with_user_content_manager() or by using g_object_new() manually if you need to set multiple construct-only properties.
Unrelated warning: webkit_web_view_get_dom_document() was removed in WebKitGTK+ 2.6. (The DOM API is only accessible via web process extensions nowadays.) You are using an old, insecure version of WebKitGTK+!
Its not clear which Webkit GTK version you are using, however concepts essentially remain same for both versions. For webkit version 2, its slightly more complicated as DOM manipulation is done on extension side.
You need to reach to the desired element - either by id e.webkit-dom-document-get-element-by-id or by name. This will return you instance of WebElement. If you use by name call, please be ware that there could be multiple elements with same name
From here you can either set the style by setting appropriate style attribute webkit_dom_element_set_attribute or other variations that can deal with styles and css rules.
Or you can take easy option and just execute the javascript that does the same thing by calling webkit_web_view_run_javascript

Codeception ElementNotVisibleException error, unable to select option, or click

I am unable to interact with an element using browser tests. It says the element is not interact-able, or not visible. This doesn't happen in Acceptance
Sometimes this solution doesn't work because the element is unavailable for some other cryptic reason.
We just had a situation where we couldn't use a <select> element to pick one of the options.
Further more, there was behaviour that was being triggered by the "change" event when the option was selected.
We were able to solve it like this.
$js = "jQuery('#chosen-option-quantity-2').val('2').trigger('change');";
$I->executeJS($js);
so the first command selects the option, and the second triggers the change event.
I hope that helps some one, even if it is me in the future.
The problem that is happening here is that the html element is being hidden by something, probably css somewhere. Because it is hidden (display:none), WebDriver can't see it, and therefore can't interact with it.
In order to fix this problem, you need to use JS to un-hide the element.
use this $I->executeJS('jQuery("#your-css-selector").show()');
This doesn't happen in Acceptance tests because PHP Browser looks at the Page Source, and so can see everything, while WebDriver see's what a user see's on the browser.
You may use PhpBrowser
It works only with HTML then how PhantomJs emulate the real browser
But, with PhpBrowser you can't see what see your browser (only HTML such I said)
Another way, try executeJs with PhantomJs as it said before

selenium webdriver is clearing out fields after sendKeys had previously populated them

The webpage that I'm testing is using knockout. On other pages on our site that are not currently using knockout I'm not having the same problem. The scenario I have is where the page opens, I enter in various required fields and click the save button. At some point between when it enters a value in the last text field and when it clicks the save button the fields that previously had values become cleared out, and thus the script can't continue. Here is an example of the code that I'm running:
driver.findElement(By.id("sku")).clear();
driver.findElement(By.id("sku")).sendKeys(itemNo);
driver.findElement(By.id("desktopThankYouPage")).clear();
driver.findElement(By.id("desktopThankYouPage")).sendKeys(downloadUrl);
driver.findElement(By.id("mobileThankYouPage")).clear();
driver.findElement(By.id("mobileThankYouPage")).sendKeys(mobileDownloadUrl);
driver.findElement(By.id("initialPrice")).clear();
driver.findElement(By.id("initialPrice")).sendKeys(initialPrice);
driver.findElement(By.id("submitSiteChanges")).click();
Like I said, between the time it enters text in the last field and the time it clicks save the fields that previously had text in them get cleared out, and thus my test fails. The problem is it doesn't always happen. Sometimes the test runs fine, other times it doesn't.
I've tried putting Thread.sleep(x); all over the place to see if pausing at certain points would fix the problem. I also have tried using javascript to wait in the background for any ajax that might be running. Also have the implicit wait of driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS). None of it seemingly has made any difference.
I'm running version 2.13 of selenium server and all my tests run on Firefox 8.
Any help on this would be greatly appreciated!
Firefox has a bug which prevents some events from being executed while the browser window is out of focus. This could be an issue when you're running your automation tests - which might be typing even if the window is out of focus.
The point is that knockout model updates are triggered (by default) with the change event. If it's not being executed, it's underlying model won't be up-to-date.
To fix this issue I triggered the change event "manually", injecting javascript into my tests.:
//suppose "element" is an input field
element.sendKeys("value");
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
jsExecutor.executeScript("$(arguments[0]).change();", element);
As you might have noticed, I'm using jQuery to trigger the change event. If you're not using jQuery on your app, you can check here how to trigger it using vanilla javascript.
Hope that helps somebody.
I had the exact same problem. I would guess also that your code works fine in Chrome but not firefox, and that it always works when you do it manually?
Anyway, the problem is likely to be that Selenium doesn't really behave the same way as a real user, and doesnt trigger the same events. When you "submit" the form, it sometimes won't have executed the "change" event on a text area, meaning that it won't have changed.
I had the same problem testing Backbone.modelbinding, which uses the "change" event to update the model from the form. Knockout also uses the "change" event, but fortunately it can also use the "keyup" event. See valueUpdate in the docs:
<input data-bind="value: someValue, valueUpdate: 'keyup'" />
Anyway, that reproducibly solved it for me, and didnt need any sleeps once I had that done. The downside is that you'd be running the event more than is necessary in production, in order to make tests work. Another downside is that you if you want to run some code when a value changes, you'll now get one event per keypress instead of one per field change, which sucks sometimes.
There is another solution, which is to make Selenium fire the change event yourself, for example: Selenium IE change event not fired. It's also suboptimal, but what can you do.
You could also try putting the focus on a button before you click it. Don't know if that will work, I haven't tried it.
I was facing the same issue, while using JavaScriptExecutor for sending keys to text fields.
Using below code in IE (same code is working with chrome):
(JavascriptExecutor) driver.executeScript("arguments[0].value = '" + value + "';", element);
After updating the code to simple "sendKeys()" method, it resolved my issue:
element.sendKeys("some text");

Selenium fails to find component after dom update (reRender)

I'm testing a richfaces application with selenium. It works fine, unless I use reRender. (for those unfamiliar with richfaces - whenever an ajax request finished, parts of the DOM are updated/chagned/removed).
So, after a reRender selenium (the IDE at least) fails to locate the elements which were within the reRendered area. Both FireBug and WebDeveloper locate the elements, and on "view source" the elements are there.
So, is there a way to tell selenium to update its DOM "knowledge" with the latest changes?
Firefox 3.5.6, latest version of Selenium IDE.
I'm using Fifefox 3.6.8, Selenium IDE 1.0.7, and RichFaces 3.3.1, running on Ubuntu Linux. I don't have this problem.
I have a simple form where the selection of a radio button triggers a reRender of an a:outputPanel. Initially, the panel is empty. If the right radio button is selected, the rendered condition is met, and the panel is rerendered with its children components. I am able to set a waitForCondition to look for an element id that will appear as a child of the panel, and I am able to verify the child elements after they appear. Selenium IDE correctly identifies these child elements when I right click in Firefox.
Selenium doesn't keep a cached version of the DOM. It can't because it is using JavaScript and all javascript DOM queries are always live.
What are you using to find the elements? If you are using Xpath/CSS selectors then there is a chance that the XPath is no longer valid or the CSS selector may not be correct.