I've made a little script which places a button in an ID 'AddToCartLayer' which is loaded dynamically.
var myVar;
myVar = setInterval(str, 1000);
function str() {
var str = 'Google',
div = document.getElementById( 'addToCartLayer' );
div.insertAdjacentHTML( 'beforeend', str );
}
Now, I can't really figure out how I can stop the script from running once the button is placed in the ID.
Could someone please help me with this. Thanks!
i think setTimeout() will work.
Related
I'm a newbie in protractor.
I've written a test with Selenium in Java and everything is OK.
But now, i need to do the same test in protractor and it driving me crazy!
I've to check the numbre of element by tagName in my page.
My code is something like this :
// Click on a button
element(by.id('e2e-idAutomate')).click();
// Wait for the next page to be present
var isPresent0 = EC.visibilityOf(element(by.tagName('ngx-carousel')));
var isPresent1 = EC.visibilityOf(element(by.tagName('cmyardneo-action-button')));
var condition = EC.and(isPresent0, isPresent1);
browser.wait(condition, 5000);
// Ok, here i want to chek the number of div by tagName
// First try!
expect<any>(element.all(by.tagName("div"))).toContain(40);
// Doesn't work... Fall in timeout!
// Second try
element.all(by.tagName("div")).then((liste) => { //Same Problem, fall in timeout
expect<any>(liste.length).toBe(40);
});
How can i read the liste return by the element.all?
Thanks!
For time our issue, please refer to http://www.protractortest.org/#/timeouts
One issue in your code:
// First try!
expect(element.all(by.tagName("div")).count()).toBe(40);
// element.all().count() is to get count of found elements
Ok,
After another tests, my problem is not about element.all
but about page change....
What i want to do is :
Open a first page
Click on a button that make à routing to a
second page
check this second page
I ve done something like that :
describe('test of application', function () {
beforeAll( () => {
TR.closeTabs();
browser.driver.manage().window().maximize();
browser.get('/ardoise');
browser.waitForAngularEnabled();
browser.wait(EC.visibilityOf(element(by.id("e2e-idAutomate"))),5000);
});
it('Click on the button', () => { // I will go on the second page
element(by.id('e2e-idAutomate')).click();
});
it('Check the second page', () => {
// brower.sleep(5000);
var isPresent0 = EC.visibilityOf(element(by.tagName('ngx-carousel')));
var isPresent1 = EC.visibilityOf(element(by.tagName('cmyardneo-action-button')));
var condition = EC.and(isPresent0, isPresent1);
// Here i want to be sure the second page is loaded
browser.wait(condition, 5000);
// Next check....
});
});
And the last condition is never OK (I've checked, the two tagName are OK!!!)
It sounds like protractor hasnot seen that a routing occurs...
I have code like this:
element(by.model("roleSelection.role")).element(by.cssContainingText('option', newRole)).click();//.then(function() {console.log('role click')})//;
where the options is loaded via a call to the server.
I can wait for the first element by doing this
browser.wait(function() {
return browser.isElementPresent(by.model("roleSelection.role")).then(function(present){
return present;
});}, 8000);
and it seems to work. But how can I wait until the "sub-element" is clickable.
I have tried this
browser.wait(function() {
return browser.isElementPresent(by.model("roleSelection.role")).then(function(present){
if (present) {
var elm = element(by.model("roleSelection.role"));
return elm.isElementPresent(by.cssContainingText('option', newRole)).then(function(subpresent) {
return subpresent;
});
}
}); }, 8000);
Have you tried clickable? Something along these lines
var EC = protractor.ExpectedConditions;
var select = element(by.model("roleSelection.role"))
var isClickable = EC.elementToBeClickable(select);
browser.wait(isClickable,5000); //now options should have been loaded by now
Well, try to this: https://angular.github.io/protractor/#/api?view=ExpectedConditions.prototype.elementToBeClickable
But, Please keep in mind, Protractor is suitable for angular webpages and interactions, and animations. For example ng-animate. So, it is not sure to working for example jquery, or other animates.
In this way:
onPrepare: function () {
// disable animations when testing to speed things up
var disableNgAnimate = function () {
angular.module('disableNgAnimate', []).run(function ($animate) {
$animate.enabled(false);
});
};
browser.addMockModule('disableNgAnimate', disableNgAnimate);
}
Or you can switch in script way in browser.executeScript().
Please see this link. It works only jquery animations.
If you not have animate problems. Use setTimeout() JS function.
I saw other protractor related post mentioning about how to wait for an element to become visible. However, recently, I ran into an opposite use case. I wanted to wait for an element until it becomes invisible. Since I could not find anything specific about it. I went ahead and came up with a solution.
var ptor = protractor.getInstance();
ptor.wait(function() {
return element(by.css('#my-css-here')).isDisplayed().then(function(isVisible){
console.log('is visible :' + isVisible);
return !isVisible;
});
}, 12000).then(function(){
//do whatever you want
});
hopefully it helps. any suggestion is welcome.
Thanks,
Using the elementexplorer (https://github.com/angular/protractor/blob/master/docs/debugging.md) I looked at the protractor object and found an answer that is working wonderfully for me:
var el = element(by.id('visibleElementId'));
browser.driver.wait(protractor.until.elementIsNotVisible(el));
From #Machtyn
This should be the correct answer:
var EC=protractor.ExpectedConditions; browser.wait(EC.not(EC.presenceOf(el)), someTimeoutInMilli);
Protractor now has invisibilityOf function built in.
var EC = protractor.ExpectedConditions;
// Waits for the element with id 'abc' to be no longer visible on the dom.
browser.wait(EC.invisibilityOf($('#abc')), 5000);
Read more for details
None of the solution working for me. Please take a look at below code:
var protractor = require('protractor');
describe('Testing', function () {
it('Should show the settings button', function () {
var EC = protractor.ExpectedConditions;
var settings = $('.settings');
var isSettingVisible = EC.visibilityOf(settings);
browser.get('http://localhost:8080/#/edomonitor');
console.log("--------------------welcome 1-------------------");
protractor.browser.wait(isSettingVisible, 10000, "Searching for settings").then(() => {
console.log("waiting complete");
}, (error) => {
console.log(error);
})
expect(2).toEqual(2);
});
});
This is my first script, in any language, so yes, i am doing something wrong and it is probably something really really stupid.
I want to wrap the H3 below in between an anchor with Mootools.
First, i tested this with a ID instead of a class. This works. Apparently ('id') is good, ('.class') is bad. But for my specific usecase i need to select the element by its class.
HTML:
<h3 class="class">test</h3>
Mootools code:
window.addEvent('domready', function () {
var test = document.getElements("h3.class");
var myAnchor = new Element('a', {
href: 'http://www.someurl.com'
});
var myWrapper = myAnchor.wraps('.class');
});
I tried to create a var and grab the element here by its class. Yet i am not sure how to call this var inside wrap string.
var myWrapper = myAnchor.wraps(test);
Now i am stuck. I hope someone can help me out here, much appreciated.
Nearly.
window.addEvent('domready', function () {
var test = document.getElement("h3.class");
var myAnchor = new Element('a', {
href: 'http://www.someurl.com'
});
myAnchor.wraps(test);
});
http://jsfiddle.net/LmBVq/
notice document.getElement (for a single element).
the opposite of wrap is adopt. you could do myAchor.adopt(test); and then inject it somewhere else.
This link (archived version) describes how to inject code from a script into an iframe:
function injectJS() {
var iFrameHead = window.frames["myiframe"].document.getElementsByTagName("head")[0];
var myscript = document.createElement('script');
myscript.type = 'text/javascript';
myscript.src = 'myscript.js'; // replace this with your SCRIPT
iFrameHead.appendChild(myscript);
}
That's ok, but what if I want to insert a function object into an iframe and get it executed in the iframe context? Let's say I have:
function foo () {
console.log ("Look at me, executed inside an iframe!", window);
}
and I want to insert foo's code inside an iframe? (function foo could be something loaded dynamically, I can't just wrap it in quotes)
I naively tried:
var scriptFooString = "<script>" + foo.toString() + "</script>"
to get the code inside function, but
I don't know how to insert it in the iframe HEAD (maybe with jquery?)
I don't know if it's the right way
I don't know what happens when if function is way more complex than that
I don't know what happens with double and single quotes in scriptFooString
Any hint?
First of all you can only accomplish this if your frame and the page displaying it is within the same domain (Due to cross-domain rules)
secondly you can manipulate dom and window objects of the frame directly through JS:
frames[0].window.foo = function(){
console.log ("Look at me, executed inside an iframe!", window);
}
to get your frame from a DOMElement object you can use:
var myFrame = document.getElementById('myFrame');
myFrame.contentWindow.foo = function(){
console.log ("Look at me, executed inside an iframe!");
}
Note that the scope in foo is NOT changed, so window is still the parent window etc. inside foo.
If you want to inject some code that needs to be run in the context of the other frame you could inject a script tag, or eval it:
frames[0].window.eval('function foo(){ console.log("Im in a frame",window); }');
Though the general consensus is to never use eval, I think its a better alternative than DOM injection if you REALLY need to accomplish this.
So in your specific case you could do something like:
frames[0].window.eval(foo.toString());
This code is the result of my research. The accepted answer also helped me a lot.
First of all, I create a simple iframe:
<iframe id="myiframe" width="200" height="200" srcdoc="<h1 id='title'>Hello from Iframe</h1><button type='button' id='fire'>Click Me!</button>
"></iframe>
For access to iframe's window and document I used this code.
const iframe = document.getElementById('myiframe');
const iframeWin = iframe.contentWindow || iframe;
const iframeDoc = iframe.contentDocument || iframeWin.document;
Finally I injected js codes into iframe:
var script = iframeDoc.createElement("script");
script.append(`
window.onload = function() {
document.getElementById("fire").addEventListener('click', function() {
const text = document.getElementById('title').innerText;
alert(text);
})
}
`);
iframeDoc.documentElement.appendChild(script);
Demo:
https://jsfiddle.net/aliam/1z8f7awk/2/
Here's my solution. I'm using jquery to insert the content, then using eval to execute the script tags in the context of that iframe:
var content = $($.parseHTML(source, document, true));
$("#content").contents().find("html").html(content);
var cw = document.getElementById("content").contentWindow;
[].forEach.call(cw.document.querySelectorAll("script"), function (el, idx) {
cw.eval(el.textContent);
});