JavaScript Protractor (Selenium) verify if input is focused - selenium

I'm trying to to test whether an element is focused using selenium webdriver in protractor. This is before AngularJS is loaded so I am having to use the driver as seen here:
var ptor = protractor.getInstance(),
driver = ptor.driver;
I also need to know how to make the test wait until the input is focused. I have to wait until a model is fired so the input is not focused for half a second as seen here:
window.setTimeout(function(){
$("input#email").focus();
}, 500);
Any idea how to verify if an input has focus after 500ms?

Based on my answer to this question, and adapting it to your case, it would look like:
it('should focus on foo input', function () {
// to wait 500ms+
browser.driver.sleep(600);
// using the Protractor 'element' helper
// https://github.com/angular/protractor/blob/master/docs/api.md#element
// var input = element(by.id('foo'));
// using findElement with protractor instance
var input = driver.findElement(protractor.By.id('foo'));
expect(input.getAttribute('id')).toEqual(browser.driver.switchTo().activeElement().getAttribute('id'));
});

I used glepretre's answer, but had to resolve the getAttribute promises for both elements using promise.all
let activeElement = browser.driver.switchTo().activeElement().getAttribute('id');
let compareElement = element(by.id('your-element-id')).getAttribute('id');
webdriver.promise.all([compareElement, activeElement]).then((id) => {
expect(id[0]).to.equal(id[1]);
});

Related

Open one page per time for Selenium WebDriver for NodeJs

I am very new for Selenium WebDriver.
I have list of URL on the array and want to open the pages ( driver.get("url")) one by one. Here is an example:
urls.forEach( (url) => {
driver.get(url); //=> want to wait here until done.
driver.getTitle(); //=> Here I want to get the title of current page before go to next url.
}
Actually, currently seems it's ran synchronization with the Promise() - it's open multiple windows one time. I want to wait until the page is done and continue. Any idea for that?
If you really want syncronous execution may be this will work better:
const {Builder} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
(async function helloSelenium() {
const service = new chrome.ServiceBuilder('/Users/sanders/Desktop/chromedriver');
const driver = new Builder().forBrowser('chrome').setChromeService(service).build();
const pages = ['https://google.com', 'https://abv.bg', 'https://facebook.com'];
for (page of pages){
await driver.get(page);
}
await driver.quit();
})();
Nodejs seems not support Synchronization for Webdriver. I switched NodeJs to .Net and it's working fine now!

Automating mat-option in testcafe

Tried automating dropdown using the below methods but the dropdown values couldn't be selected.
Method 1:
const comboOption = Selector("mat-option").child("span").withExactText("Hello");
await t.click(comboOption);
Method 2:
ClientFunction(() => {
document.getElementsByClassName('mat-option-text')[0].innerText = 'Hello';
document.getElementsByClassName('mat-option-text')[0].click();
return "Hello";});
The mat-option tag is not within mat-select. It is outside mat-select and within div tag.
Are there other ways to achieve automating mat-option ?
Thank you for the code snippets.
As far as I understand, you are trying to click an option element in another select element.
I created a simple test that should perform the steps you described:
import { Selector } from 'testcafe';
fixture`Getting Started`
.page`http://devexpress.github.io/testcafe/example`;
const selectElement = Selector('#preferred-interface');
const optionElement = selectElement.find('option');
test('My first test', async t => {
await t
.click(selectElement)
.click(optionElement.withText('Both'))
.expect(selectElement.value).eql('Both');
});
If I misunderstood your question, could you please share a simple example of your .html and a detailed description of
what you want to do in the test and which results you expect?

How to make Selenium WebdriverJS code execute in sequence

I'm relatively new to using WebDriverJS and trying out a simple script to begin with.
However, am facing a lot of issues and did not find any resources that were helpful.
Scenario being Tested:
Launch browser
Navigate to google.com
Capture Title of the page
Add a wait statement (driver.sleep)
Enter some text in Search box
Here is the code snippet:
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
var driver = new webdriver.Builder().forBrowser('chrome').build();
driver.get("http://www.google.com");
driver.getTitle().then(function(title) {
console.log("Title is: " + title);
});
console.log('Before sleep');
driver.sleep(10000);
console.log('After sleep');
driver.findElement(By.name('q')).sendKeys("Hello");
Here is the output:
Before sleep
After sleep
DevTools listening on ws://127.0.0.1:52449/devtools/browser/aea4d9eb-20ee-4f10-b53f-c2003c751796
Title is:
As can be seen, it is a very straight forward scenario. However none of it is working as expected.
Below are my queries/ observations:
console.log for Before/ After sleep is executed as the very first statement even before browser is launched whereas it is not clearly the intention.
Title is returned an empty String. No value printed.
driver.sleep() never waited for the specified duration. All commands got immediately executed. How to make driver hard wait when driver.sleep is not working?
Tried adding implicit wait, however that resulted in error as well.
What are the best practices to be followed?
I did not find very many helpful webdriver javascript resources and it is not clear how to proceed.
Any guidance is appreciated. TIA.!
I referred the documentation as well and similar steps are given there. Not sure if there is some issue from my end. https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs
Assuming that you example is written in JavaScript and runs on Node.js, it looks to be as if you would miss all the waiting for asynchronous functions to have finished processing. Please be aware that most functions return a promise and you must wait for the promise to be resolved.
Consider the following example code:
const {Builder, By, Key, until} = require('selenium-webdriver');
(async function example() {
let driver = await new Builder().forBrowser('firefox').build();
try {
await driver.get('http://www.google.com/ncr');
await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
await driver.wait(until.titleIs('webdriver - Google Search'), 1000);
} finally {
await driver.quit();
}
})();

Ionic 3 infinite-scroll simulate in e2e test jasmine/protractor

If you go here: http://ionicframework.com/docs/api/components/infinite-scroll/InfiniteScroll/
Inspect the demo and click the last item on the list:
Then in the console type: $0.scrollIntoView()
Infinite Scroll is never triggered.
Is there a way to programmatically trigger infinite-scroll in protractor context?
The implementation of the scroll in your example rely on the speed/velocity of the scroll which I guess falls far from the expected range when scrollIntoView is called.
One workaround is to simulates a smooth scroll by emitting multiple scroll events over a reasonable time. The idea is to reproduce as close as possible the behavior of a real user.
Some browsers already provides the option via scrollIntoView (supported by Chrome 62) :
$0.scrollIntoView({behavior: "smooth", block: "end"});
Using the accepted answer, in my case, I used ion-infinite-scroll as the argument.
Complete test to check if more content is loaded in Ionic:
describe('Scroll', () => {
it('should load more when reached end', async () => {
let list = getList();
let currentCount = await list.count();
const refresher = element(by.tagName('ion-infinite-scroll')).getWebElement();
let count = 0;
while(true){
browser.executeScript(`arguments[0].scrollIntoView({behavior: "smooth", block: "end"});`, refresher);
browser.sleep(1000); // wait for data to be loaded from api
list = getList();
let newCount = await list.count();
expect(newCount).toBeGreaterThanOrEqual(currentCount)
expect(newCount).toBeLessThanOrEqual(currentCount * 2)
if(newCount === currentCount){
break;
}
currentCount = newCount;
count++;
}
expect(count).toBeGreaterThan(0);
})
});
function getList() {
return element(by.className(pageId + ' list')).all(by.tagName('ion-item'));
}

Wait until page is fully loaded with selenium and intern js

I am trying to create a UI automation test with intern js , but i m getting problem on waiting until the page is fully loaded. My code starts searching for element before the page is loaded. Can some one help me on this.
My code:
define([
'intern!object',
'intern/chai!assert',
'Automation/ConfigFiles/dataurl',
'Automation/pages/login/loginpage',
'intern/dojo/node!fs',
'intern/dojo/node!leadfoot/helpers/pollUntil'
], function (registerSuite, assert,dataurl, LoginPage,fs,pollUntil) {
registerSuite(function () {
var loginPage;
var values;
return {
setup: function () {
var data = fs.readFileSync(loginpage, 'utf8');
json=JSON.parse(data);
console.log('###########Setting Up Login Page Test##########')
this.remote
.get(require.toUrl(json.locator.URL))
.then(pollUntil(this.remote.findById('uname').isDisplayed(),6000)// here i want to wait until page is loaded
.waitForDeletedByClassName('loading').end().sleep(600000)// here i want to wait until loading component is disappered
values = json.values;
loginPage = new LoginPage(this.remote,json.locator);
},
'successful login': function () {
console.log('##############Login Success Test############')
return loginPage
.login(values.unamevalue,values.pwdvalue)
},
// …additional tests…
};
});
});
I m trying to use pollUntil . But I m not sure weather I should use it or not.
pollUntil is a good thing to use here, but it doesn't look like you're actually waiting for polling to finish. Your setup method needs to return the command chain that includes pollUntil so that Intern will know it needs to wait, something like:
var setupPromise = this.remote
.get(require.toUrl(json.locator.URL))...
values = json.values;
loginPage = new LoginPage(this.remote, json.locator);
return setupPromise;
Alternatively, you could pass your LoginPage class the chain:
var setupPromise = this.remote
.get(require.toUrl(json.locator.URL))...
values = json.values;
loginPage = new LoginPage(setupPromise, json.locator);
In this case Intern won't wait for setup to complete, but your LoginPage code will implicitly wait for the setupPromise to complete before doing anything else. While this will work, the intent isn't as clear as in the previous example (e.g., that Intern should wait for some setup process to complete before proceeding).