jquery programmatic popup window - javascript

I'm new to Jquery, so please bear with me. I'm trying to create a function that will programmatically open popup windows. I'm running the following code in Firefox, and it seems to work except that the popup windows disregards the toolbar/menubar/scrollbars/resizable/location parameters (they are still visible/functional and I would like to disable all of them):
wparams[0] = {windowURL:"site.html",height:100,width:100,left:500,top:500,toolbar:0,menubar:01,scrollbars:0,resizable:0,location:0}
var launchWindow = function(p)
{
$('.popup').popupWindow(wparams[p]).trigger("click");
}
var begin = function()
{
launchWindow(0);
}
I would like the popups I'm using jQuery-swip popup plugin (http://swip.codylindley.com/popupWindowDemo.html), am wondering what's wrong with the above code.
Also, when I try to run this code in chrome/safari (typing begin(); in the console) it returns undefined, whereas in Firefox it runs. I'm also confused as to why this is happening.
Thanks.

I didn't understand 'when' you want to open the popup, if when the page complete loading, so it should be
$(document).ready(function() {
launchWindow(0);
});
Also can you explain to me why use trigger(click)??? As of the plugin documentation, this should work like that
var launchWindow = function(p)
{
$('.popup').popupWindow(wparams[p]);
}

Does this work?
wparams[0] = {windowURL:"site.html","height:100,width:100,left:500,top:500,toolbar:0,menubar:01,scrollbars:0,resizable:0,location:0"}

That's a weird way to define the "wparams" array - what happens if you do this:
var wparams = [
{windowURL:"site.html", height:100, width:100, left:500, top:500, toolbar:0, menubar:01, scrollbars:0, resizable:0, location:0}
];
It's not really clear why you're setting that up as an array; I guess maybe there might be other popup configurations stored in it. If that's the case, you'd just write them inside those square brackets, separated by commas.

Related

Nightwatch ERROR: Unable to locate element: using: css selector

I am a newbie to nightwatch and javascript and for the life of me I am getting stuck at some weird places. I am trying to do a simple test which just clicks on three different tab menu items one at a time. When I run the code I get an ERROR: Unable to locate element: "#Performing_AF" using: css selector.
If I go ahead and use the css selector directly opposed to using elements the code works. Can someone guide me as to where I am going wrong?
The URL I am testing is: https://www.nypl.org/
Here is /pages/homepage.js
var elements = {
searchbutton: '.nyplHomepageApp button[name = "Search Button"]',
Authortalksconversations: '.titleTabs #tab-0',
Exibitions: '.titleTabs #tab-1',
Performing_AF: '.titleTabs #tab-2',
Other_Events: '.titleTabs #tab-3',
DonateButton: '#donateButton',
Shop: '#shopTopLink',
loadicon: '.dcom-loader',
searchboxbutton: 'button[type="submit"]',
inputsearch: '.desktopSearch-form-inputBox #desktopSearch-form-searchInput'
};
var quicksearch = {
go: function()
{
this
.waitForElementVisible('body', 6000)
.api.pause(2000)
.click('#Exibitions')
.pause(2000)
.click('#Other_Events')
.pause(2000)
.click('#Performing_AF')
}
};
module.exports = {
elements,
commands: [quicksearch]
};
And here is tests/homepagetest.js
module.exports = {
'Q': function(browser) {
var goto = browser.page.homepage();
goto.go;
//browser.end();
}
}
As I mentioned in my comments above, if you remove all the pauses from the test it will work. I'm not exactly sure the reasons behind that. It would be better to use waitForElementVisible or waitForElementPresent whenever possible. pause() will make your tests flaky and unreliable.
The way you would use these is
click on a tab
wait for some element on that tab to be visible / present
click on the next tab and repeat
If you really would like to keep the pauses you can get it to work by adding a few variables at the top of your go function and using those variables instead of the #someElement syntax.
go: function() {
var exibitions = this.elements.Exibitions.selector;
var otherEvents = this.elements.Other_Events.selector;
var performingAf = this.elements.Performing_AF.selector;
this
.waitForElementVisible('body', 6000)
.api.pause(2000)
.click(exibitions)
.pause(2000)
.click(otherEvents)
.pause(2000)
.click(performingAf)
}
This works fine for me
ul.titleTabs > li#tab-2
Your css selector also works out for me. What is the error that you're facing?

Testing tab navigation order

In one of our tests, we need to make sure that the tab keyboard navigation inside a form is performed in the correct order.
Question: What is the conventional way to check the tab navigation order with protractor?
Currently we are solving it by repeating the following step for as many input fields existing in a form (code below):
check the ID of the currently focused element (using getId())
send TAB key to the currently focused element
Here is the example spec:
it("should navigate with tab correctly", function () {
var regCodePage = new RegCodePage();
browser.wait(protractor.ExpectedConditions.visibilityOf(regCodePage.title), 10000);
// registration code field has focus by default
expect(regCodePage.registrationCode.getId()).toEqual(browser.driver.switchTo().activeElement().getId());
// focus moved to Remember Registration Code
regCodePage.registrationCode.sendKeys(protractor.Key.TAB);
expect(regCodePage.rememberRegistrationCode.getId()).toEqual(browser.driver.switchTo().activeElement().getId());
// focus moved to Request Code
regCodePage.rememberRegistrationCode.sendKeys(protractor.Key.TAB);
expect(regCodePage.requestCode.getId()).toEqual(browser.driver.switchTo().activeElement().getId());
// focus moved to Cancel
regCodePage.requestCode.sendKeys(protractor.Key.TAB);
expect(regCodePage.cancelButton.getId()).toEqual(browser.driver.switchTo().activeElement().getId());
// focus moved back to the input
regCodePage.cancelButton.sendKeys(protractor.Key.TAB);
expect(regCodePage.registrationCode.getId()).toEqual(browser.driver.switchTo().activeElement().getId());
});
where regCodePage is a Page Object:
var RegCodePage = function () {
this.title = element(by.css("div.modal-header b.login-modal-title"));
this.registrationCode = element(by.id("regCode"));
this.rememberRegistrationCode = element(by.id("rememberRegCode"));
this.requestCode = element(by.id("forgotCode"));
this.errorMessage = element(by.css("div.auth-reg-code-block div#message"));
this.sendRegCode = element(by.id("sendRegCode"));
this.cancelButton = element(by.id("cancelButton"));
this.closeButton = element(by.css("div.modal-header button.close"));
};
module.exports = RegCodePage;
It is working, but it is not really explicit and readable which makes it difficult to maintain. Also, another "smell" in the current approach is a code duplication.
If the current approach is how you would also do it, I would appreciate any insights about making it reusable.
I think the PageObject should define a tab order list, since that is really a direct property of the page, and should be expressible as simple data. An array of items seems like a sufficient representation, so something like:
this.tabOrder = [ this.registrationCode, this.rememberRegistrationCode, this.requestCode, this.cancelButton ];
Then you need a bit of generic code that can check a tab order.
function testTabOrder(tabOrder) {
// Assumes TAB order hasn't been messed with and page is on default element
tabOrder.forEach(function(el) {
expect(el.getId()).toEqual(browser.driver.switchTo().activeElement().getId());
el.sendKeys(protractor.Key.TAB);
});
}
Then your test would be something like:
it('has correct tab order', function() {
var regCodePage = new RegCodePage(); // this should probably be in the beforeEach
testTabOrder(regCodePage.tabOrder);
});
Of course, this assumes each element has a "getId()" method that works. (That seems like a reasonable assumption to me, but some environments may not support it.)
I think this keeps the tab-order nicely isolated on the PageObject (so its easy to keep in sync with the page content and doesn't get lost in the code that verifies the order). The testing code seem "optimistic" (I suspect the real world will introduce enough problems that you will end up expanding this code a bit).
I haven't tried any of this yet, so feel free to downvote if this doesn't work. :)
Also, I believe the forEach loop will work as-is, but I wouldn't be surprised if it needs some more explicit promise handling to make the dependencies explicit.

Strange behavior from ko.editables

I'm using the ko.editables plugin for knockout, and it doesn't appear to be caching the previous value correctly. Does anyone have experience with this plugin?
If I do something like this:
var item = { Name: ko.observable("initial") };
selectedItem = ko.observable(item);
ko.editable(selectedItem);
selectedItem.beginEdit();
selectedItem().Name("second");
selectedItem.rollback();
What ends up happening is that selectedItem().Name is still "second", even though it should be "initial".
I looked into the source file, but I don't understand enough about the way JavaScript handles variables to know if what I'm seeing is right or wrong.
I set a breakpoint in the following place within ko.editables.js:
result.rollback = function () {
if (inTransaction()) {
result(oldValue); //breakpoint
inTransaction(false);
}
};
What I found was that oldValue had picked up the new value of the observable, even though commit was never called. Everything I've tried looks exactly like the samples. What am I missing?
Update:
I've updated the code sample. My original code does have the ko.editable() line in it, but thank you to Robert.westerland for pointing it out. It still doesn't work with this extra line.
I know this is an old post, but could be useful for others. I think you might need to call "commit" before the "beginEdit", and I also had to include "true" as a second parameter when calling ko.editable.
Your updated code::
var item = { Name: ko.observable("initial") };
selectedItem = ko.observable(item);
ko.editable(selectedItem, true);
selectedItem.commit();
selectedItem.beginEdit();
selectedItem().Name("second");
selectedItem.rollback();

Issue with retrieving object data on IE 8 on Windows XP or 2003

This is an interesting problem that I am facing with JavaScript and IE8 on Windows XP and Windows 2003. I create an object on the page and then retrive information about that object (for example, its version). When trying to get the version, I am running this code:
var myObject = document.getElementById(objectId);
console.log(myObject.version);
What is interesting is that this code works on every single browser except IE8 on Windows XP and 2003. I've done some debugging and this is where things get interesting.
myObject is not null but myObject.version is undefined. So what I did is I added an alert in between so the code is now as follows:
var myObject = document.getElementById(objectId);
alert(myObject.version);
console.log(myObject.version);
The alert results in "undefined", however, the console.log is now resulting in the actual version. If I add an alert before this alert of anything (let's say alert("something")) then the second alert has the actual version now. I am assuming this is a timing issue (for some reason the object needs sometime to be able to provide the data stored in it?) but I am not sure what kind of timing issue this is or how to approach it.
Sorry for the long description but any help is appreciated.
document.getElementById doesn't return an object. It returns a DOM element. So, you expect to see a .version property in a DOM element, which by the official W3C specification is missing (or at least I don't know about this).
I'm not sure what you are expecting to see in .version, but if it is something custom then you should create a custom object like that:
var o = { version: "..." }
console.log(o);
You said that this may be a time issue. If that's true then I'll suggest to try to access the .version property after the DOM is fully loaded. You can use jQuery for the purpose:
$(document).ready(function() {
var myObject = document.getElementById(objectId);
alert(myObject.version);
console.log(myObject.version);
});
You can add a setTimeout in your function till the .version property is there.
var f = function(callback) {
var check = function() {
var myObject = document.getElementById(objectId);
alert(myObject.version);
console.log(myObject.version);
if(typeof myObject.version !== "undefined") {
callback(myObject.version);
} else {
setTimeout(check, 1000);
}
}
setTimeout(check, 1000);
}
What happens if you put the <script>...</script> tag with the js code at the end of the html file? In my opinion, the code is executed when the DOM is not ready. If you put it in the end, then it will be executed after it's loaded.

Add function to existing JQuery plugin

Is it possible to add a function to a plugin without modifying the actual plugin? Can I do something like this in my site's js file?
$.fn.Watermark.Refresh = function() {
$.Watermark.HideAll();
$.Watermark.ShowAll();
}
or
(function($){
$.fn.Watermark.Refresh = function() {
$.Watermark.HideAll();
$.Watermark.ShowAll();
};
})(jQuery);
neither worked, the first says $ is undefined, the second that jQuery is undefined...
ideas?
Solution: Either method works, just include the jquery file before the site js file.
You can add those functions if you want to, but you'll have to make sure that you're also loading jQuery itself and the plugin to be modified. If you're getting those errors (that jQuery or "$" are not defined), then you have not correctly done that.
Now, though it's true that you can add those functions, I have to wonder what the point would be. If I were to do this, for example:
$.fn.css.myFunction = function() { return "hello world"; };
then it would be possible to call it:
var str = $.fn.css.myFunction();
but so what? What good does that do me? I don't think it's very useful.
Make sure you are including the plugin after jQuery.

Categories

Resources