As I am writing angularJS Jasmine test case for iframe print, but it showing "Cannot read property 'open' of undefined". Please find below the snippet of the code
Source code:
$scope.print = function() {
var iFrame = document.getElementById("printingFrame");
var iFrameDoc = iFrame.contentDocument;
iFrameDoc.open();
var contents = "text";
iFrameDoc.write(contents);
iFrameDoc.close();
iFrame.contentWindow.focus();
iFrame.contentWindow.print();
};
Test Case:
describe("just a test", function () {
it("should print iframe content", function () {
locals.$scope.print();
});
});
Error:
TypeError: Cannot read property 'open' of undefined
Anyone know why the following unit test does not pass?
Related
I'm trying to convert some old ruby tests (which used cucumber, phantomjs and capybara) into JavaScript (using cucumber, phantomjs and selenium) as my project is 100% node based and I want to remove the Ruby dependency.
When I run the tests, they all pass. The problem is, I've not created the conditions for the test to pass yet so a pass is impossible. I'm not sure where I'm going wrong.
Here is my world.js file:
var {defineSupportCode} = require('cucumber');
var seleniumWebdriver = require('selenium-webdriver'),
By = seleniumWebdriver.By,
until = seleniumWebdriver.until;
function CustomWorld() {
this.driver = new seleniumWebdriver.Builder()
.withCapabilities(seleniumWebdriver.Capabilities.phantomjs())
.build()
// Returns a promise that resolves to the element
this.waitForElement = function(locator) {
var condition = seleniumWebdriver.until.elementLocated(locator);
return this.driver.wait(condition)
}
}
defineSupportCode(function({setWorldConstructor}) {
setWorldConstructor(CustomWorld)
});
And here is my step definitions file:
require('dotenv').config();
var chalk = require('chalk');
var {defineSupportCode} = require('cucumber');
var seleniumWebdriver = require('selenium-webdriver'),
By = seleniumWebdriver.By,
until = seleniumWebdriver.until;
defineSupportCode(function({ Given, When, Then }) {
Given(/^I show my environment$/, function (next) {
console.log(chalk.green("Running against:" + process.env.TARGET_URI))
next()
})
When(/^I visit "(.*?)"$/, function (url) {
return this.driver.get(url);
})
Then(/^I should be on "([^"]*)"$/, function(page_name) {
this.driver.get(process.env.TARGET_URI+'/'+page_name)
.then(function() {
return this.driver.getCurrentUrl();
})
})
Then(/^I should see "([^"]*)"$/, function (text) {
var xpath = "//*[contains(text(),'" + text + "')]";
var condition = seleniumWebdriver.until.elementLocated({xpath: xpath});
return this.driver.wait(condition, 5000);
});
})
The only possible tests that could be passing there are: When(/^I visit "(.*?)"$/... and Given(/^I show my environment$/...
For reference, here is my .feature file too:
Feature: Test the global header works as expected
Scenario: Header components should exist
Given I visit "/hello"
Then I expect to see a ".c-logo-bar" element
And I expect to see a ".c-search-bar" element
And I expect to see a ".c-main-nav-bar" element
Any ideas where I'm going wrong?
I want to access web elements using the $$ or elements command using webdriverio. I know they return array of web elements but I am facing tough time accessing them, probably because I am new to webdriverio.
I tried the below code:
var webdriverio = require('webdriverio');
var options = {
desiredCapabilities: {
browserName: 'firefox',
},
};
var client = webdriverio.remote(options);
client
.init()
.url(some url)
.isExisting(selector).then(function(isExisting)) {
if(isExisting) {
var bText = this.$$('textarea[name="message_text]') // this code onwards it is not working
bText.then(function (res) {
console.log(res.length);
console.log(res);
res.value.forEach(function (elem) {
return this.click(elem.ELEMENT)
.setValue(elem.ELEMENT,'some text')
.keys('Enter')
})
})
In the above code, I can see the array res in console but the forEach loop doesn't seem to work. I want to perform click, setValue and keys('Enter') for each of the element present in this.$$('textarea[name="message_text"]') also not able to understand why the returned elements are in a form of JSON objects?
If anyone could guide me in right direction that would help!
Use 'client' instead of 'this' to select the elements.
var bText = client.$$('textarea[name="message_text]') // this code onwards it is not working
bText.then(function (res) {
console.log(res.length);
console.log(res);
See use of runner here -
https://github.com/webdriverio/webdriverio/issues/1043
#ChristianB's suggestion worked actually,since webdriverio's standalone app is built on top of webdriverjs whose methods return promises we need to resolve them properly.I was able to do this using map & Promise.all :
var bText = this.$$('textarea[name="message_text]')
bText.then(function (res) {
console.log(res.length);
console.log(res);
var promises = res.map(function (elem) {
return client
.elementIdClick(elem.ELEMENT)
.setValue(elem.selector,'some text')
.keys('Enter')
})
return Promise.all(promises)
})
I am writing test cases using Karma Mocha.
Following is my function:
fun : function()
{
if(a == 1)
$("#test").hide();
}
We set the DOM element property based on some condition.
While writing its test:
it('fun', function (){
var a = 1;
// how do I test the DOM element.
// Is it possible to access the DOM element of the source file in the test file.
})
I tried using chai-jquery but it accesses only body and not the other elements.I guess it works on DOM elements of test file.
Can anyone please help.?
I assume you have your jQuery loaded upon testing then you would select you element with $('#test') and then do you tests.
Like so:
describe('obj.fun', function (){
before(function() {
$('<div id="test"></div>').appendTo(document.body);
});
after(function() {
$('#test').remove();
});
it('should hide the element when a is 1', function() {
var $test = $('#test');
expect( $test.is(':hidden') ).to.be.false;
obj.a = 1;
obj.fun();
expect( $test.is(':hidden') ).to.be.true;
});
});
In Sencha Touch 2 I have a controller which calls a custom 'prepopulate' method on button tap:
Ext.Ajax.request
({
method: 'GET',
url: myurl, //defined outside
withCredentials: true,
headers:{Authorization : auth},
success: function(response){
var data;
if(response.responseText.length > 0)
data = Ext.JSON.decode(response.responseText.trim());
console.log(data);
var fv = me.getFiscal();
console.log(fv);
fv.prepopulate(data);
Ext.Viewport.animateActiveItem('fiscal', me.getSlideLeftTransition());
},
failure: function(response){
Ext.Msg.alert('Server Error', 'Server down :( please try again later');
}
}
);
View code:
prepopulate : function (data) {
var me = this;
var companyTextField = me.down('#fiscalForm').down('#companyTextField');
var vatField = me.down('#fiscalForm').down('#vatField');
var fiscalCodeTextField = me.down('#fiscalForm').down('#fiscalCodeTextField');
var addressTextField = me.down('#fiscalForm').down('#addressTextField');
var cityTextField = me.down('#fiscalForm').down('#cityTextField');
var zipTextField = me.down('#fiscalForm').down('#zipTextField');
var countryTextField = me.down('#fiscalForm').down('#countryTextField');
console.log(vatField);
console.log((data.vat));
if(data){
if(data.company_name)
companyTextField.setValue(data.company_name);
if(data.vat)
vatField.setValue(data.vat);
if(data.fiscal_code)
fiscalCodeTextField.setValue(data.fiscal_code);
if(data.address)
addressTextField.setValue(data.address);
if(data.city)
cityTextField.setValue(data.city);
if(data.zip)
zipTextField.setValue(data.zip);
if(data.country)
countryTextField.setValue(data.country);
}
console.log(vatField);
}
The AJAX call works fine and it calls on success the prepopulate method passing the data retrieved from the server.
I try to initialize the TextFields using setValue() but the form looks 'brand new' when I open it using the browser
console.log() tells me that the _value private field is correctly set though... I'm groping in the dark right now ... any insight?
Thank You in advance.
M.
As you suggest the data i correctly retrieved and display in the console with the console.log, nonetheless the browser don't find any visible fields to modify the value when the setValue() is called.
The solution so far is to modify the ajax request as follows:
Ext.Ajax.request
({
....
....
success: function(response){
....
Ext.Viewport.animateActiveItem('fiscal', me.getSlideLeftTransition());
//view must be in the viewport before modifying data:
var task = Ext.create('Ext.util.DelayedTask', function () {
var fv = me.getFiscal();
fv.prepopulate(data);
});
task.delay(1000);
.....
....
...
..
.
I'm trying to call a function defined in another module using this.evaluate().
The code snippet(calling the function) is:
this.waitFor(function check() {
var re = this.evaluate(universe.answer(couponElement, url));
if (re != 'no' & re!='yes' & re!=null) {
couponObj.push(re);
and the module in which the function is defined is like this:
var require = patchRequire(require);
var utils = require('utils');
exports.answer = function(couponElement, url) {
var lblInvalidCoupon = 'lblInvalidCoupon';
var tolTipCouponinner='tolTipCouponinner';
var txtFCCoupondisocunt = 'txtFCCoupondisocunt';
var btnRemoveFCCoupon = 'btnRemoveFCCoupon';
var check = $('#txtCouponCode').css('backgroundImage');
if (check.indexOf('ajax-loader.gif')>-1){
return 'no';
} else {
if (document.getElementById(lblInvalidCoupon)!=null){
Basically, I want to call the function using this.evaluate but unable to do so.
First, try with the simplest evaluate: remote.message event to capture console.log from page.
casper.on("remote.message", function(msg) {
console.log("[page] " + msg);
});
this.evaluate(function () {
console.log("Hi phantomworld! I am hello-ing from remote page!");
});
Next, check if jQuery is present:
this.evaluate(function () {
console.log(typeof jQuery);
});
If it says, [page] function, jQuery is present in the page. You need to dig more...
If not, inject it:
var casper = require('casper').create({
clientScripts: [
'includes/jquery.js'
]
});
You didn't actually pass the answer function to casper.evaluate, but you called it instead. The problem is that in this way answer was not executed in page context and because of this $ is not defined. casper.evaluate which executes a function in page context is sandboxed. It cannot use variables which are defined outside. The passed function must be self contained.
To fix this the arguments which are consumed by answer can be passed as additional parameters to casper.evaluate.
Change the line
var re = this.evaluate(universe.answer(couponElement, url));
to
var re = this.evaluate(universe.answer, couponElement, url);
If JQuery is not present in the page you need to follow sudipto's answer.