I want to be able to click inside a search box which is on the page and then click submit and have a couple expect statements.
So far I have this:
it('should redirect to the correct page', function(){
browser.driver.findElement(by.id('header-search')).click();
browser.driver.findElement(by.id('header-search')).sendKeys("aaa");
//element.all(by.id('header-search')).sendKeys("tfgm");
expect(browser.getCurrentUrl()).toEqual("http://localhost:8080/web/customer/account");
});
When I run protractor all it does is click on the box but does not paste in the text. Anyone have any ideas about what is going wrong?
There is no need to click the search field before entering keys, you can do that directly.
If the user is supposed to click a submit button after entering their search terms, don't forget to make protractor click it:
it('should redirect to the correct page', function(){
element(by.id('header-search')).sendKeys('foo');
$('[type="submit"]').click();
//Expect-statements
});
I would suggest taking a look at Elementor(Elementor Github Repo Here) to help you figure out what elements to call.
When you get it installed, there is a bug(Link to issue) that currently is active, however it will still find your elements for you(gives you the by.id/by.css/by.buttonText) for you to plug into your tests.
Keep in mind that when you start Elementor, it will open a NEW instance of Chrome. You will need to duplicate the chrome tab before using the Elementor plugin(right click the tab> Duplicate).
As for your tests, you shouldn't NEED to click the search element. .sendKeys() will essentially "click" that element. The way to think of how sendKeys() works is it finds the element you specify, then will plug in the keys you state into that element.
I would suggest trying to change your statement to be:
this.headerSearch = by.id('headerSearch'); //Or any by.something element
it('should redirect to the correct page', function() {
element(this.headerSearch).sendKeys("aaa\n"); // the \n will represent the "enter key"
});
You could go even further to parameterize the test and separate out your statements to follow the Page Object test methodology a bit better by doing:
This set of code will be in a PO file named something like SearchPage.js(remember the file needs to be exported):
this.headerSearch = by.id('headerSearch');
this.setHeaderSearch = function(search) {
element(this.headerSearch).sendKeys(search);
};
This will be in your main test(it will need to import your SearchPage.js page object file):
it('should do something like input keys into element', function(){
searchPO.setHeaderSearch('send some keys\n'); // the \n will represent the "enter key"
expect(browser.getCurrentUrl()).toEqual("http://localhost:8080/web/customer/account");
});
If you could provide everyone the HTML of the element your testing, we could help you out better.
I hope this was somewhat helpful to you!
Which browser are you using with protractor? If you are using Firefox, this should be an issue. sendKeyscannot work on Firefox browser.
Related
I have a task where I need to automate Sign in form authentication. For this example, I'll show you Tiktok authentication form (Mobile interface, not desktop. E-mail and password option)
If I enter text values into the fields programmatically, the Login button won't become active, and if I manually focus on the fields with a mouse click, the value disappears. These are two lines of code I run to put the value in:
let email_input = document.getElementsByName("email")[0];
email_input.value = 'sample#email.com';
I understand it needs to trigger a certain event to assign a value into it's JS model, but I can't figure out how to do it. I have tried sending change or input events onto this text field with no luck using this code:
let email_input = document.getElementsByName("email");
email_input[0].value = 'sample#email.com';
custom_event = new Event('input');
email_input[0].dispatchEvent(custom_event);
// tried also change, textInput like so:
custom_event = new Event('change');
email_input[0].dispatchEvent(custom_event);
But this does not seem to help.
So my goal is to put values into both fields Email and Password in the way it will be detected and Log in button would become active.
Any suggestion would be much appreciated
You should first focus needed input element and then execute document.execCommand with insertText command:
let email_input = document.getElementsByName("email");
email_input[0].focus();
document.execCommand('insertText', false, 'sample#email.com');
With this method input\textarea value modification should be captured by all major frameworks including Angular and Vuejs. This modification will be processed by frameworks the same way as if user pressed "Paste" option in browser main menu.
It all depends...
Who/what are you? A normal browser user? A bot? The browser author?
Because code like this is useless...
let email_input = document.getElementsByName("email")[0];
What document are you referring to? Who's document? Did you inject this instruction into the page and executed it?
You're not telling us where you're coming from, but anyway...
If you are the browser author, or you can run JavaScript macros from your browser (ie: the Classic browser) then you can do something like this...
var Z=W.contentWindow.document.querySelectorAll('input[type="password"]');
if(Z.length>0){
Z[0].value='password123';
Z=W.contentWindow.document.querySelectorAll('input[type="email"]');
if(Z.length>0){Z[0].value='email#abc.com';}
}
To automatically populate such fields, and if you also want you can SubmitButtonID.click() the submit button for as long as the isTrusted property is not tested by the website.
Continued...
Test if normal (non-custom) submit button exists and click...
Z=W.contentWindow.document.querySelectorAll('input[type="submit"]');
if(Z.length>0){
if(Z[0].hasAttribute('disabled')){Z[0].removeAttribute('disabled');} <--- Enable it if disabled
Z[0].click(); <--- automate click
}
Currently I am working with protractor and Selenium web Driver.
I have the following problem:
I have a html page, and I make protractor clicking a button. Then a window pops up. This window contains a text box with the Name "Description":
<input type="Text" name="Description" ... />
Now when I try the following:
element(by.css('[name="Description"]')).sendKeys("rabbababab");
The browser does nothing, but protractor does not throw an error. No text is typed into the TextBox. Unfortunatelly, the name is the only way to identfy the input-TextBox.
What am I doing wrong?
Selecting directly by name works as well:
element(by.name('Description')).sendKeys("rabbababab");
OK guys, ive found the issue.
It wasnt an alert, its just a div, and all other controls are locked for user Input. but the Dialog covers a TextBox, wich has the same css-properties. So protractor just writes into the covered TextBox and i couldnt see it...
The Problem is solved
Sometimes if that element is inside iframe then you have to switch to that iframe. Just check that is there any iframe or modal available?
otherwise your code seems correct.
There is an inbuilt prompt handler in protractor where you can identify it and then send the data into the input field that you want. Here's how -
browser.Alert.sendKeys("rabbababab");
Note: The pop up window should have an input that it can accept some data into it else you command will fail.
If the above solution doesn't work then try sending data by switching to the pop-up and then sending text to it. Here's how -
browser.driver.switchTo().alert().sendKeys('rabbababab');
If at all there are many prompts, then you can use window handles function to switch to the one that you want. Here's how -
browser.getAllWindowHandles().then(function(handles){
browser.switchTo().window(handles[1]).then(function(){ //change the array index based on your pop-up's count
element(by.css('[name="Description"]')).sendKeys("rabbababab");
});
});
Hope it helps.
Maybe you have multiple objects which have name="Description" in your application.
You can find this in Chrome:
Right-click on the object
Click on Inspect element
Press CTRL+F
Type [name="Description"] and see how many results it finds.
element(by.css('[name="Description"]'))
is the same as
$('[name="Description"]')
If you find more than one, then you can try the following:
1. Try a click on the field before sending keys to it
2.
// This will search for the element of input with the name="Description" attribute
$('input[name="Description"]').sendKeys('rabbababab');
3.
You can try to put the following line, before sending keys to it :
browser.waitForAngular(); // wait until the angular app loads
Let us know how it worked.
Try using this,
$('input [name=Description]').sendKeys("rabbababab");
or
element(by.css('input [name=Description]')).sendKeys("rabbababab");
I'm attempting to implement an experiment in Qualtrics, but I've run up against this wall.
A button appended to a qualtrics question using JQuery will refresh the page, regardless of whether or not .click or .event have been defined. In my design this has the effect of wiping all the responses a participant has given up until that point, which is probably the last thing I want to happen.
My code is too complicated (a.k.a. poorly written) to post here. However you can replicate the error by creating a new survey consisting of a single 'descriptive text' question and attaching this code. Here jq refers to Jquery
Qualtrics.SurveyEngine.addOnload(function(){
/*Place Your Javascript Below This Line*/
jq('.QuestionBody').append('<button>This shouldn\'t do anything</button>')
});
This link is an example of the above.
https://sydneypsy.qualtrics.com/SE/?SID=SV_1ZGMxfENT0ykxBr
Why does this happen? Does anyone know to prevent it?
Source: robbrit
This is the default behaviour of a button. If you want to change it, do something like this:
$("button selector").click( function(event) {
event.preventDefault();
});
In your case, I would give the button an ID to use for a selector.
I have a form which is using a select list to jump around my site. This is currently using onclick window.location so user selects the page and presses go and it goes to that page.
I now need to add a small text box for the user to type in a code (say 123456) and then when they click go, it should go to the url selected, but with the [CODE] being the number entered in the box. I discovered jquery replaceAll so it gave me the idea to have this in the select html:
http ://jumptothispage.com/parts/p[CODE]/edit
http ://jumptothispage.com/jobs/j[CODE]/edit
When you press go, it would replace all [CODE] in that html with the code entered and then jump to that page selected, e.g.
http ://jumptothispage.com/parts/p123456/edit
http ://jumptothispage.com/jobs/j123456/edit
I am already using jquery on my site so makes sense to try and utilize that again. I'd appreciate a pointer and or other suggestions instead.
Thanks,
Paul.
A workaround: Store the code in a cookie, so at least it's not visible to every person who looks at the URL bar. Then in every onclick, fit it into the URL to send the user to the "right" page.
Or, have your select option's value literally read CODE, which your onclick interprets to mean "The user hasn't set the code yet." When the user types in the code, store it in a variable (in the example below, realcode), and you can then do this:
$('select#navigation option').each(function(idx, el) {
$(el).attr('value', $(el).attr('value').replace(/CODE/, realcode));
});
Newbie question...
The objective:
I intend to have an HTML text input field as a kind of command line input.
An unordered HTML list shows the 5 most recent commands. Clicking on one of the last commands in this list should populate the command line input text field with the respective command (in order to re-execute or modify it).
An unordered HTML list contains a result set. Clicking on an ID in this list should bring the respective ID into the command line input text field.
In HTML (DHTML):
Works as expected: when clicking on the the link the command line input text field is populated with a recent command.
<li>here would be one of the recent commands</li>
In Javascript file:
Doesn't work as expected: when clicking on the the link the command-line-input-text-field gets populated with the respective value (as it should), BUT then it seems like the full HTML page is being reloaded, the text input field and all dynamically populated lists become empty.
function exec_cmd(cli_input_str) {
// a lot of code ...
// the code that should provide similar behavior as onclick=... in the DHTML example
$('.spa_id_href').click(function(){document.getElementById('cli_input').value = document.getElementById('cli_input').value + this.firstChild.nodeValue;});
}
Now the Question:
Besides a potential Javascript (syntax) error, what could cause the browser to reload the page?
In both cases, you do nothing to cancel the default function of clicking on a link.
In the plain HTML example, the link to the top of the page is followed.
You don't specify what the href attribute for the second example looks like, but whatever it is, it will be followed.
See http://icant.co.uk/articles/pragmatic-progressive-enhancement/ for a good explanation of event cancelling and good event design. See http://docs.jquery.com/Tutorials:How_jQuery_Works for some jQuery specific guidance.
Change
$('.spa_id_href').click(function(){...
to
$('.spa_id_href').click(function(evt){...//notice the evt param
and in the function, call
evt.preventDefault();
It seems that you just follow the link target URL. That is because you do not prevent the default click action:
e.preventDefault(); // `e` is the object passed to the event handler
// or
return false
Alternatively, you can set up a href starting with #, or not use <a> element at all (use <span style="cursor:pointer"> instead) β if itβs not a real link of course.
It's basically related to event cancelling...
Try this:
try { (
e || window.event).preventDefault();
}
catch( ex )
{
/* do Nothing */
}
While the other answers here make excellent points about canceling events, you will still run into problems if your JavaScript contains errors which prevent your event-canceling code from being run. (As might be the case if you're, say, debugging your code.
As an additional precaution, I strongly recommend you not use href="#" on links which only trigger scripts. Instead, use the void operator:
...
The reason for this is: when the event is not canceled, the browser will attempt to load the URL supplied by the href attribute. The javascript: "protocol" tells the browser to instead use the value of the accompanying code unless that value is undefined. The void operator exists explicitly to return undefined, so the browser stays on the existing page β with no reload/refresh β allowing you to continue debugging your script.
This also allows you to skip the entire event-canceling mess for JS-only links (though you will still need to cancel events in code attached to links which have a "fallback" URL for non-JS clients).