I am working on a browser recording test, in which I am entering a value into an Input field with an
auto search trigger functionality.
document.getElementById('InputFieldWIthSearchFunctionality').value = "Saurav";
But the search is not triggered if I set the value to the field as above.
Kindly help.
Just setting the value will not call the onchange and/or oninput event listeners of the input field. The auto search trigger is probably listening to this event.
You can dispatch both of these events manually to the input field:
const elem = document.getElementById("InputFieldWIthSearchFunctionality");
// create onchange event
const onchangeEvent = document.createEvent("HTMLElements");
onchangeEvent.initEvent("onchange", false, true);
// create oninput event
const oninputEvent = document.createEvent("HTMLElements");
oninputEvent.initEvent("oninput", false, true);
// dispatch events to the input field
elem.dispatchEvent(onchangeEvent);
elem.dispatchEvent(oninputEvent);
This definitely works in Chrome and all browsers using Chromium, I did not test any other browser, that would be up to you.
Information about manually dispatching events taken from this answer: https://stackoverflow.com/a/2856602/7846567
Think of it this way... by setting the value directly using JS, you are shortcutting the typical UI that a real user would use thus causing this issue. JS should be used sparingly (almost never) if you are trying to write tests that act like a user would and now you can see why.
In Java you would do this
driver.findElement(By.id("InputFieldWIthSearchFunctionality")).sendKeys("Saurav");
which would cause the search to fire in your case.
Related
I have created an on screen keyboard (osk) to be used in a kiosk style React app. The osk works as it should and inputs desired text etc. into the appropriate elements. My problem is that inputting text with the osk does not trigger a change event on the target so my onChange handler never gets called. I have attempted to trigger the change event after inserting my my text with the osk as shown below however, my existing onChange handler does not get called the way it does when entering text with the keyboard. What is the best 'React' way to handle this? PS- I am not using jQuery. Thanks!
//update element text from osk
this.props.target.value = (this.props.target.value + btnText);
//attempt to trigger change event
this.props.target.dispatchEvent(new Event('change'));
//input updated from osk
const ce = React.createElement;
ce("input", {
id: "PasswordText",
type: "password",
data: "text",
onClick: this.clickHandler,
defaultValue: this.props.accessPassword,
onChange:this.changeHandler})
//change handler
changeHandler(e) {
this.setState({
stateObject: e.target.value
});
}
The problem, as Mark point, is due to React not listening to those events (or not trusting them).
To trigger the input event, you have to edit the Extension:
Find the dir where the extension is stored on your system
Open script.js with your favorite editor
Find the virtualKeyboardChromeExtension_click function and add the following after the switch statement:
function virtualKeyboardChromeExtension_click(key, skip) {
[...]
switch (key) { // <- find the switch statement
[...]
} // <- after the close brace add the following 4 lines code:
var inputEvent = new Event('input', {bubbles:true});
if(typeof virtualKeyboardChromeExtensionClickedElem !== "undefined") {
virtualKeyboardChromeExtensionClickedElem.dispatchEvent(inputEvent);
}
// you are done
Save and reload the extension.
NOTE: If you are using chrome it will give you errors and warnings about modified and untrusted extension. But as you are developing a kiosk mode app I suppose you can switch to chromium, enter developer mode and use the Load unpacked extension button to load your modified extension
I had the same problem with a Virtual Keyboard extension for Chrome. Found out on an issue in react's repository that react hears the input event, not the actual change event.
In your case the solution would be to trigger this event, in my case I opted out of generic virtual keyboards and looked for a more react oriented solution (i.e. a virtual keyboard react's library)
A little late but I hope this helps some one else.
Cheers bro
I am using a simplified example to describe the issue I am facing.
I have the following HTML markup:
<input ng-model="something" style="margin-top:8px;"/>
And, I have two HTML buttons:
<button id='submit'>Save</button>
<button id='btnGetAnalyzerInput'>Generate Analyzer File </button>
I used jQuery's change event on my input (to track whether any changes have been made to the input - by maintaining a simple JS variable).
When the user clicks "Generate Analyzer file button", what I want to is this:
Look up the JS variable to find out whether any changes have been made.
If yes, then prompt the user to save changes (window.dialog)
However, I find that when the focus is still on the input element, and when the button is clicked, the click event runs before the OnChange event. In all other cases, it is the OnChange event which gets fired before the click event (and so my code works as expected).
Is there any way to ensure that for such a scenario, the click event runs after the onChange event?
I am using Google Chrome to test my application.
Note :
Both events work as expected - the OnChange event gets fired when the textbox loses focus.
I can't use the keypress event since I want to track changes.
You could have the click event call the same function as the OnChange event. Something like this:
function OnChange(){
//Do stuff for on change;
}
function ClickEvent(){
OnChange();
//continue with generate stuff
}
You you may need to set up and pass in arguments to the OnChange function, depending on how you are accessing the data you need. If you need more guidance, post more of your code.
Im sending keys to a input filter using sendkeys and supposed to be it will update the contents of the table, I check its screenshot and it placed the characters on the field. unfortunately after sendkeys, it doesnt trigger either keyup/keydown.
How to trigger keyup or keydown on casper?
Code:
this.sendKeys('input[name=\"filterString\"]', 'string');
casper.sendKeys() should have triggered the keyup and keydown events, because it uses native browser events which should be indistinguishable from user input in other browsers.
You trigger it yourself by keeping focus and then triggering those events:
this.sendKeys('input[name=\"filterString\"]', 'string', {keepFocus: true});
this.page.sendEvent("keydown");
this.page.sendEvent("keyup");
this.page.sendEvent("keypress");
For this you can use the underlying PhantomJS function page.sendEvent().
There exists a website implemented with ExtJS 3.1.
I want to pre-fill some fields automatically. The problem is, that some fields are not validated by ExtJS when automatically filling them.
I can trigger the validation by firing ExtJS's blur event:
field.fireEvent('blur', field);
However, I don't want to do this. I want that validation to be triggered by a normal event triggered via jQuery:
$field.blur();
What I am asking here is the following:
How to trigger the blur event of a textbox in the same way the browser does it, so that also ExtJS's event handlers run?
BTW: The reason why I don't want to manually fire the ExtJS event is simple: This solution seems to work for ExtJA 3.1 but no longer for 4.2 and I don't want to write special handling code for every version of ExtJS.
If you want to play around a little bit:
Here is the URL: https://www.pantaenius.com/en/service/login/request-a-quote.html?utm_source=http%3A%2F%2Fwww.pantaenius.com%2Fen%2Famerican-yacht-insurance.html&utm_medium=direct&domain_segment=33
Open it in Chrome, open Chrome's developer console and paste the following text:
delete console.log
var $city = jQuery('#ext-comp-1080');
var city = Ext.ComponentMgr.all.filterBy(function(x) { return x.isXType('combo') && x.id==='ext-comp-1080'; }).items[0];
var blurEventFireFn = city.events.blur.listeners[0].fireFn;
city.events.blur.listeners[0].fireFn = function(field) { console.log('ExtJS blur fired!'); blurEventFireFn(field); };
When you click in the City field and then in some other field, you will see the output ExtJS blur fired! in the console. You will see the same output when you execute city.fireEvent('blur', city);. However, you won't see that output when you execute $city.blur();, $city.trigger('blur'); or
var event = document.createEvent('HTMLEvents');
event.initEvent('blur', true, true);
$city.get(0).dispatchEvent(event);
Any ideas how to create this bridge between normal events and ExtJS events would be greatly appreciated.
Simulating the native event with your bit of code does work (in non-IE browsers):
var event = document.createEvent('HTMLEvents');
event.initEvent('blur', true, true);
$city.get(0).dispatchEvent(event);
However you should avoid the problem rather than giving it a weird cure, by using the validator of the field instead of a blur event listener. This way, the setValue method of the field will trigger its validation...
If you're really stuck with it, instead of adding a (probably fragile) layer of complexity by simulating events, I would just call the onBlur method of the fields directly. That's the handler that is added to the DOM by Ext. It is present in 3.x and 4.x, and it doesn't rely on specific browsers...
Is there is any way to detect text box value changed , whether users changes it explicitly or some java script code modified the text box? I need to detect this change.
To track for user changes you can add a handler for key presses:
$(selector).keypress(function() {
// your code
});
Update: besides watching for key presses,
you can use the change function to watch from changes via JavaScript. It won't work immediatly for user changes (is only called after the input loses focus), but together with the keypress I believe you cover all cases:
$(selector).change(function() {
// the same code
});
setTimeout(function() { $(selector).val("changed"); }, 2000); // Will trigger the change
Edit: sorry, it seemed to work for JavaScript too, but I was mistaken... This question, however, will be able to solve your problem (tested with setTimeout, and it was able to detect the change).
I posted an example in jsFiddle. With this new watch plugin, you no longer need keypress or change: it will work for key typing, copy/pasting, JavaScript, etc.