React - selenium tests - javascript

Solved, see answer below
I test a React app with selenium.
I need to change the value of an input field, which is linked to the state of the object. In short (relevant parts of the code), a change in this input allows it's value to be submited only if it is not empty:
# react object
render: function(){
<input ... onChange={this.handleTextChange} className="myInput" />
<button onClick={this.handleSubmit}>Submit</button>
},
handleTextChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function() {
if(this.state.text.length > 0) {
// relevant code that is never executed
// because although we change the value of the input, the state does not update
}
},
The code works but I cannot find a way to test it because I cannot find any js manipulation which would update the input AND reflect in the state of the object.
I tried the following solutions
# value update
self.selenium.execute_script("var input = document.querySelectorAll('input.myInput')[0]; form.value = 'New message!'");
The word 'New message!' actually appears in the input but does not update the state of the object.
I then tried focusing on the input and triggering a keyup event, without success
# try focus and keyUp
# source https://stackoverflow.com/questions/596481/simulate-javascript-key-events
self.selenium.execute_script("""
var form = document.querySelectorAll("input.messageFormInput")[0];
form.focus();
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
keyboardEvent[initMethod](
"keydown", // event type : keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // viewArg: should be window
false, // ctrlKeyArg
false, // altKeyArg
false, // shiftKeyArg
false, // metaKeyArg
40, // keyCodeArg : unsigned long the virtual key code, else 0
0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
""")
I tried the same solution with jQuery as explained here (Is it possible to simulate key press events programmatically?), but it does not work either.
Any idea is very welcome. Thanks!

My bad, I was not aware of
self.selenium.find_elements_by_class_name('myClass')[0].send_keys("hello")
Which actually solves the issue. Thanks to Chris Hawkes for sending me in the right direction.

Related

How to fire a keyboard keypress using Keycode

I have a scenario where I have to prepare a JS method where Tab key should fire . i.e. When the Function is executed Tab button click should fire. preferably using Key code.
You can dispatch keyboard events, but the results might be less than overwhelming.
As shown below, you can dispatch an event with appropriate properties, but in some browsers the values are empty and the browser virtually ignores it. You can tab to the button and press "Enter" to click it. It dispatches a tab, but focus doesn't move and the associated event doesn't report the values set in the constructor.
Typing into the input shows the type of result you should get. Try it in lots of browsers.
function showEventProperties(evt) {
document.getElementById('details').innerHTML = ['type','key','code','keyIdentifier','charCode','which','keyCode'].map(function(key) {
return key + ': ' + evt[key];
}).join('<br>');
}
function sendTab(node) {
var evt = new KeyboardEvent('keypress', {
'view': window,
'bubbles': true,
'key': 'Tab',
'charCode': 9,
'keyCode': 9,
'which': 9
});
node.dispatchEvent(evt);
}
window.onload = function() {
document.addEventListener('keypress', showEventProperties, false);
}
<input onkeypress="showEventProperties(event)">
<br>
<button onclick="sendTab(this)">Do tab</button><button>Next button</button>
<p id="details"></p>
You can also try the older initKeyEvent.

Programmatically pressing Alt 0 with JavaScript

What I'm trying to do is run a script (JS) that selects a test box. It's ID field name is JMan. Once it selects that field I am trying to programmatically have my code perform the key combination ALT+0 and then delay itself for 5 seconds. By the way I'm performing this in the IE browser.
function myFunction() {
var keyboardEvent = document.createEvent("keyboardEvent").;
document.getElementById("JMan");
}
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
keyboardEvent[initMethod](
"keydown", // event type : keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // viewArg: should be window
false, // ctrlKeyArg
true, // altKeyArgenter code here
false, // shiftKeyArg
false, // metaKeyArg
48, // keyCodeArg : unsigned long the virtual key code, else 0
0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
The detection event handler is a no-frills method of detecting Alt-0. You might consider more sophisticated checking to do things like determine if another key was pressed between the Alt and 0 (i.e this code will treat Alt-1-0 as if it were Alt-0 or Ctrl-Alt-0 as if it were Alt-0)(At least it checks if you hold down Alt-0). This is mainly because key events differ considerably between browsers and I wanted to make something that will hopefully work on the majority.
The button in this example fires a minimal "Alt-0" event designed for the event handler to catch (or you should be able to type Alt-0 into the window).
function fireAlt0() {
console.log("firing event");
window.dispatchEvent(new KeyboardEvent("keydown", { key: "0", altKey: true }));
}
function detectAlt0(event) {
if ("keydown" == event.type) { // we might want to use the same function for any of ( keydown, keypress, keyup ) events
if (event.key == "0" && event.altKey && !event.repeat) {
console.log("Open a window!");
}
}
}
window.addEventListener("DOMContentLoaded", function () {
// Use keydown because keypress won't fire for the Alt-0 combination (since it doesn't produce a visible character)
window.addEventListener("keydown", detectAlt0, false);
document.getElementById("button").addEventListener("click", fireAlt0, false);
}, false);
<button id="button">fireAlt0</button>

Simulate JavaScript Keypress on Text Field (Safari)

I`m trying to simulate a keypress event in a text field via javascript but seems that nothing works on Safari. I can see that some examples works at document level but none of them works with my text field.
Could please someone help-me? Thanks.
Here is my code:
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
keyboardEvent[initMethod](
"keypress", // event type : keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // viewArg: should be window
false, // ctrlKeyArg
false, // altKeyArg
false, // shiftKeyArg
false, // metaKeyArg
40, // keyCodeArg : unsigned long the virtual key code, else 0
0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
);
document.getElementById('mytextbox').dispatchEvent(keyboardEvent);
Obs: the textInput event don't work in my scenario.

JavaScript onfocus attribute and key events

I am trying to simulate an keyinput in JavaScript on a textbox, in Firefox. The textbox has an onfocus=" this.value='' " attribute. A simulation + my code can be found at
Working code:
var divy = document.getElementById("eventListener");
divy.focus();
var inputText = '';
for(var i = 0; i < ('asd').length; i++)
{
var event = document.createEvent('KeyboardEvent');
event.initKeyEvent ('keydown', true, true, null, false, false, false, false, 0, 0)
divy.dispatchEvent(event);
inputText += ('asd').charAt(i);
var event = document.createEvent('KeyboardEvent');
event.initKeyEvent ('keypress', true, true, null, false, false, false, false, 0, ('asd').charCodeAt(i))
divy.dispatchEvent(event);
divy.value = inputText;
var event = document.createEvent('KeyboardEvent');
event.initKeyEvent ('keyup', true, true, null, false, false, false, false, 0, 0)
divy.dispatchEvent(event);
}
divy.blur();
My question is, how to properly simulate the input (without jquery!) so that the second textbox doesn't have an empty value. And also as the focus event is only once thrown, why gets the value erased each time.
UPDATE:
As I thought that the divy.focus(); Method might need some time to execute the onfocus event in attributes, I set up a timeout to send the key events, using:
windows.setTimeout("fireKeys2()", 5000);
But this also does not seem to work. The test is located here
http://jsfiddle.net/hPBNA/23/
UPDATE 2:
I figured out the problem myself, it seems like if element.value has been set to '' this way (element.value = '') element.setAttribute('value', someText) is not able to change it. Accessing the element.value property instead gave me the right results.
Tested in Firefox 22. Don't know if its reproducible on other versions.
I figured out the problem myself, it seems like if element.value has been set to '' this way (element.value = ''), element.setAttribute('value', someText) is not able to change it. Accessing the element.value property instead gave me the right results.
Tested in Firefox 22. Don't know if its reproducible on other versions.
John

Preventing ckeditor to display character on keypress

I have a CKEditor 3.0 instance 'editor' and on its 'key' event a listener is attached so that when that function is returning false it should not type that key character on editor, that is if key 'k' is pressed it should not be displayed on the editor if the function is returning false
editor.on('key', function(e)
{
alert(""+e.data.keyCode);
return false;
});
I used above code for this but it is not working, means the character is getting typed on the editor
Trying the same using a plugin where on keypress of keycode 65 the other language character should show up instead of english language character.
CKEDITOR.plugins.add( 'typing',
{
init: function( editor )
{
editor.addCommand( 'insertcharacter',
{
exec : function( editor )
{
alert(editor.id);
alert(editor.name);
editor.on('key', function(e)
{
alert("Hello"+e.data.keyCode);
if(e.data.keyCode == 65)
{
editor.insertText('Other Language Character');
}
return false;
});
}
});
can u suggest me any solution for this.
Thanks
found the answer recently. this worked for me in the latest version(4.x).
editor.document.on('keypress', function(e) {
e.data.preventDefault(); // this will prevent the default action for any event
//your code goes here
});
In v4 you can use editor.on('key') and cancel() the event when the appropriate key is pressed.
So to ignore k keypresses,
editor.on('key', function(evt) {
var keyCodeToIgnore = 'K'.charCodeAt(); // Upper case K. Only one k key.
var pressedKeyCode = evt.data.keyCode;
if ( pressedKeyCode === keyCodeToIgnore ) {
evt.cancel();
}
}
(That wouldn't prevent 'k's being added by other means, of course, such as pasting.)
See http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-key
You can also configure the editor to block specified keystrokes. Using that you can specify case. So to ignore k and not K:
config.blockedKeystrokes = [75]; // To ignore k and K: [75, 107]
Though you'd probably want to keep the default blockedKeystrokes as well.
See http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-blockedKeystrokes
The first method lets you do other stuff of course. You could drive people crazy by ignoring a 'u' if the previous keypress was a 'q', for example.
use following code before return from function to Cancel/block the character/event.
e.cancelBubble = true;
e.returnValue = false;
e.cancel();
e.stop();
return false;
where e is in parameter of function
I came looking for a way to bind something to the the enter key press. Except I'm using contenteditable div tags, and maybe that made the above solutions not work for me.
However I came to this, that seems to be working perfectly
$(function () {
CKEDITOR.instances['<the DOM ID of your element>'].on('key', function (e) {
if (e.data.keyCode === 13) {
//yeet
e.cancel();
}
});
});

Categories