How to verify text in a spinner/loader? - katalon-studio

I am trying to capture and verify the text which appears in a spinner after clicking on a link. Is it possible to perform this type of test in Katalon?
I created the following keyword:
#Keyword
def activitySpinner(){
def activSpinner = WebUI.getText(findTestObject('Object Repository/WMS/Page_Dashboard/div_System Activity Loading Please Wait )'))
return activSpinner
}
Then I tried the following script to use the keyword:
def actSpinner = CustomKeywords.'com.wms.modules.general.ModuleKeywords.activitySpinner'()
if (WebUI.verifyMatch(actSpinner, 'System Activity Loading... Please Wait :).*', true, FailureHandling.STOP_ON_FAILURE)){
println("The spinner shows the text: " + actSpinner)
}
The DOM shows the following:
<script type="text/javascript" src="http://10.150.2.43:10093/js/jquery/jquery.page.1562162263.js"></script>
When I right click and open the above, I see the following for that particular link:
$j(document).on("click", "#system_activity", function() {
showLoader('System Activity Loading...');
window.location=BASE_URL + "erp/wms/statistics";
The “Please Wait :)” part was shown here on the page:
function showLoader(msgText,visible){
if(typeof(msgText)==='undefined') msgText = "Loading...";
var theme = "a",
textVisible = true,
textonly = false;
html = "";
msgText = msgText + ' Please Wait :)';
if(typeof(visible)==='undefined'){
$j.mobile.loading( 'show', {
text: msgText,
textVisible: textVisible,
theme: theme,
textonly: textonly,
html: html
});
}else{
$j.mobile.loading( 'hide' );
}
The spinner shows the text "System Activity Loading... Please Wait :)" and this is what I need to verify in Katalon Studio but get the following error after running the script:
09-12-2019 10:55:07 AM Test Cases/regression/WMS/C16320 - Activity Module
Elapsed time: 1m - 4.408s
com.wms.modules.general.ModuleKeywords.activitySpinner:92
com.wms.modules.general.ModuleKeywords.invokeMethod:0
Test Cases/regression/WMS/C16320 - Activity Module FAILED.
Reason:
com.kms.katalon.core.exception.StepFailedException: Unable to get text of object 'Object Repository/WMS/Page_Dashboard/div_System Activity Loading Please Wait )'
at com.kms.katalon.core.webui.keyword.internal.WebUIKeywordMain.stepFailed(WebUIKeywordMain.groovy:64)
at com.kms.katalon.core.webui.keyword.internal.WebUIKeywordMain.runKeyword(WebUIKeywordMain.groovy:26)
at com.kms.katalon.core.webui.keyword.builtin.GetTextKeyword.getText(GetTextKeyword.groovy:88)
com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
at TempTestCase1568303703564.run(TempTestCase1568303703564.groovy:21)
Caused by: com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: 'Object Repository/WMS/Page_Dashboard/div_System Activity Loading Please Wait )' located by 'By.xpath: //*[(text() = 'System Activity Loading... Please Wait :)' or . = 'System Activity Loading... Please Wait :)')]' not found
Any ideas?

You are getting the com.kms.katalon.core.webui.exception.WebElementNotFoundException exception that basically says the element isn't in the DOM at that moment. Maybe it hasn't loaded yet.
First, since I'm not sure findTestObject('Object Repository/WMS/Page_Dashboard/div_System Activity Loading Please Wait )') is correctly defines the element, so let's change that with the following:
TestObject spinner = new TestObject().addProperty("css", ConditionType.EQUALS, ".ui-icon-loading")
Next is to try adding a wait condition (wait 30 seconds for the element to appear) before getting the element text. Combination of both would result in something like
#Keyword
def activitySpinner(){
WebUI.waitForElementVisible(spinner, 30)
def activSpinner = WebUI.getText(spinner)
return activSpinner
}
Katalon docs for the WebUI.waitForElementVisible().

Related

Protractor page object definition not working as expected

I apologize for the slightly vague title, I'm not sure how exactly to word this.
I have my Page Object which, with one exception, works perfectly. Here's the excerpt:
module.exports = function(){
this.facilityList = element(by.name('facility')).all(by.tagName('option'));
this.randomFacility = element(by.name('facility')).all(by.tagName('option')).count().then(function(numberOfItems) {
var rnum = parseInt(Math.random() * numberOfItems);
return rnum;
}).then(function(randomNumber) {
element(by.name('facility')).all(by.tagName('option')).get(randomNumber)
});
}
I can access and use facilityList just fine. But then I realized that I'm almost always doing the same thing to facilityList so why don't I just create another line to make it choose a random one. So I create randomFacility using the code from the main conf.js.
It didn't work. The error I see displayed is:
Failed: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See http://git.io/v4gXM for details"
I'm confused. Is this saying I can't do all that processing in the page object to get the random one or do I simply have to manipulate facilityList in the conf.js and be done with it?
You nee to know the mechanism about how protractor to find element. Protractor only to start find element from page when protractor's action API be called, like getText(), click(), count() etc.
So when you define variable to represent certain element on page, when Nodejs execute this line, protractor won't to start find element from page:
// page object login.page.js
module.exports = function LoginPage(){
this.sumbitButton = element(by.css('#submit'));
this.countName = element.all(by.css('.username')).count();
}
// use page object in conf.js
var LoginPage = require('./login.page.js');
var loginPage = new Loginpage();
When Nodejs execute line var loginPage = new Loginpage();, all lines in function LoginPage will be executed.
When execute the first line, protractor not to find element from current open page,
When execute the second line, protractor will find element from current open page, But at this time point, protractor is possible to launching browser with a blank page, the target page have not been opened or navigated to.
To fix your problem, you need to define randomFacility as class's Method, rather than Property:
module.exports = function() {
this.facilityList = element(by.name('facility')).all(by.tagName('option'));
this.randomFacility = function() {
return element(by.name('facility'))
.all(by.tagName('option')).count()
.then(function(numberOfItems) {
console.log('count: '+numberOfItems);
var rnum = parseInt(Math.random() * numberOfItems);
console.log('random index: '+rnum);
return rnum;
})
.then(function(randomNumber) {
console.log('argument randomNumber: '+randomNumber);
return element(by.name('facility'))
.all(by.tagName('option')).get(randomNumber)
});
}
};
// how to use
pageObject.randomFacility().then(function(ele){
return ele.click();
});

protractor browser.actions().mouseMove() not showing hover effects

I am new to protractor and trying to add tests for a slider panel which is closed by default and hovering mouse over will open it and then there are a list of items on the slider panel to pick.
<div class="slider" [ngClass]="{ closed: state === 1, open: state === 2}" (click)="onClick($event)" (mouseover)="onMouseOver($event)" (mouseleave)="onMouseLeave($event)">
I tried multiple ways, none of them work.
First attempt:(no hover effect, ie, do nothing)
browser.actions().mouseMove(element(by.css('.slider.closed'))).perform();
Second attempt:( got an error: An invalid or illegal selector was specified)
browser.actions().mouseMove(element(by.css('[(mouseover)="onMouseOver($event)"]'))).perform();
Third attempt: (got an error: No element found using locator)
browser.actions().mouseMove(element(by.css('[mouseover="onMouseOver($event)"]'))).perform();
This should work, unless you have multiple elements with class .slider. At which point, you might try including a parent object, or another locator strategy.
browser.actions().mouseMove($('.slider')).perform();
I used webdriver and made it work. browser.executeScript('arguments[0].click()',browser.driver.findElement(By.css('.slider')));
I just have the same problem, after 2 hours, I found this work for me:
src: java mouse over using javascript
let loginElement = await driver.findElement(By.id('header-user'));
let strJavaScript = "var element = arguments[0];"
+ "var mouseEventObj = document.createEvent('MouseEvents');"
+ "mouseEventObj.initEvent( 'mouseover', true, true );"
+ "element.dispatchEvent(mouseEventObj);";
await driver.executeScript(strJavaScript, loginElement);
I got the same issue when run tests with firefox
and find out a solution as below
if (browser.isFirefox) {
var script = `if(document.createEvent) {
var evObj = document.createEvent('MouseEvents');
evObj.initEvent('mouseover', true, false);
arguments[0].dispatchEvent(evObj);
} else if (document.createEventObject) {
arguments[0].fireEvent('onmouseover');
}`;
browser.executeScript(script, elm.getWebElement());
return elm.click();
} else {
return browser.actions()
.mouseMove(elm.getWebElement())
.click()
.perform();
}
Test with:
Protractor: 5.1.1
Selenium: 3.4.0

Ionic Worklight Page not displaying after HTTP request

I'm having an issue displaying the content in the page after the Worklight http request has been executed.
The weird thing is that when I go to another page and I come back, the content gets displayed. It's like if it needs to be refreshed or something. I can see the console.log() data was received, but page was not refreshed.
This is my code:
$stateProvider.state('accounts', {
url: "/accounts",
templateUrl: 'views/accounts.html',
controller: function($scope, $ionicScrollDelegate, $rootScope){
var req = new WLResourceRequest("/adapters/JavaMQ/bankmq/getAccounts/"+$rootScope.globalReqUserId, WLResourceRequest.GET);
req.send().then(function(resp){
var x2js = new X2JS();
resp.responseText = x2js.xml_str2json(resp.responseText); //to JSON
$scope.reqUserId = resp.responseText['ASI_Message']['Riyad_Bank_Header']['Requestor_User_ID'];
$scope.accountsList = resp.responseText['ASI_Message']['Repeating_Group_Section']['Repeating_Group'];
console.log($rootScope);
})
}
});
UPDATE:
I noticed that I also keep getting the following when I moved the project to Windows (Never happened in my mac)
Deviceready has not fired after 5 seconds
Channel not fired: onCordovaInfoReady
Channel not fired: onCordovaConnectionReady
I don't really know Worklight but the documentation indicate that the send().then() handles both the onSuccess and onFailure.
Maybe the then() is expecting 2 parameters like this:
var request = WLResourceRequest(url, method, timeout);
request.send(content).then(
function(response) {
// success flow
},
function(error) {
// fail flow
}
);
If that doesn't work, can you put a breakpoint at the start of var x2js = new X2JS(); and tell us what happens?

Facebook page update script

I have a greasemonkey script that tries to make a status update when a facebook page loads.
But when I try to submit, I get the message:
"This status update appears to be blank. Please write something or
attach a link or photo to update your status."
I am guessing that I am bypassing some input validation routine that is called when a real user types in the status.
Here is what I have beem trying.
Consider a FB page like: https://www.facebook.com/IFeakingLoveScience
function setmsg()
{
textHolder.focus();
var vntext=textHolder.value;
textHolder.value = postvalue;
textHolder.focus();
postbutton = document.getElementsByClassName( "_42ft _4jy0 _11b _4jy3 _4jy1" )[0];
postbutton.focus();
textHolder.focus();
setTimeout(postmsg, 4000); // Give the link in post value load.
}
function postmsg()
{
textHolder.focus();
textHolder = document.getElementsByClassName( "uiTextareaAutogrow input mentionsTextarea textInput" )[0];
textHolder.value = postvalue1 + "\n" + postvalue2; // set the value again just in case that helps...
textHolder.focus();
postbutton.click();
}
setTimeout(setmsg, 1000); // give a sec for the page to load
Any clues?
Regards,
Manoj
Assuming you are running your script on your 'Home' page on facebook, set your status update as the value of the hidden input named "xhpc_message" .
//set input value
document.getElementsByName('xhpc_message')[0].value = 'yourstatusupdategoeshere';
//submit button click
document.getElementsByClassName('_42ft _4jy0 _11b _4jy3 _4jy1 selected')[0].click()

UIAlert handling in UIAutomation

I am trying to test the presence of UIAlertview in app.
From the documentation i have added the following handler in the starting of the script.
UIATarget.onAlert = function onAlert(alert) {
var title = alert.name();
// add a warning to the log for each alert encountered
UIALogger.logWarning("Alert with title '" + title + "' encountered!");
UIATarget.localTarget().captureScreenWithName("alert_" + (new Date()).UTC());
// test if your script should handle the alert, and if so, return true
// otherwise, return false to use the default handler
return false;
}
But this handler is not being called when the alert pop ups. Can any one help me with this?
It might happen if the alert pops up very soon. You can still access its title with
UIATarget.localTarget().frontMostApp().alert().scrollViews()[0].staticTexts()[0].value();
Note: leave out scrollViews()[0] prior to iOS7.