I'm trying to write a Greasemonkey script for Facebook and having some trouble with the funky page/content loading that they do (I don't quite understand this - a lot of the links are actually just changing the GET, but I think they do some kind of server redirect to make the URL look the same to the browser too?). Essentially the only test required is putting a GM_log() on its own in the script. If you click around Facebook, even with facebook.com/* as the pattern, it is often not executed. Is there anything I can do, or is the idea of a "page load" fixed in Greasemonkey, and FB is "tricking" it into not running by using a single URL?
If I try to do some basic content manipulation like this:
GM.log("starting");
var GM_FB=new Object;
GM_FB.birthdays = document.evaluate("//div[#class='UIUpcoming_Item']", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (i = GM_FB.birthdays.snapshotLength - 1; i >= 0; i--) {
if (GM_FB.birthdayRegex.test(GM_FB.birthdays.snapshotItem(i).innerHTML)) {
GM_FB.birthdays.snapshotItem(i).setAttribute('style','font-weight: bold; background: #fffe88');
}
}
The result is that sometimes only a manual page refresh will make it work. Pulling up the Firebug console and forcing the code to run works fine. Note that this isn't due to late loading of certain parts of the DOM: I have adding some code later to wait for the relevant elements and, crucially, the message never gets logged for certain transitions. For example, when I switch from Messages to News Feed and back.
Aren't they using ajax to load content in a div? You can find the element which is being updated by using Firebug for example.
When you click something and the URL changes, but with a # on the URL and after this some text, it means the text is not a path, it's a parameter, the browser won't change the page you are, so since GreaseMonkey inject the script on the page loads it won't inject again, because the page is not reloading.
As in your example the URL facebook.com/#!/sk=messages is not navigating away from facebook.com/ it will not fire window.load event.
So you need to find which element is being changed and add an event listener to that element, you can do is using Firebug as I mentioned before.
After you find out what element is getting the content, you have to add an event listener to that element and not the page (GreaseMonkey adds only on the window load event).
So in you GM script you would have ("air code")
document.getElement('dynamic_div').addEvent('load', /*your script*/);
Related
New to testing with protractor, actually new to test automation in general so hopefully this is posted in the right place. Apologies if not, please advise.
I am trying to test elements on a pages which are only displayed after a response to REST call. The page in question has two TABS, I click on the non-active TAB, it goes active, loads the TAB framework, then a few seconds (depending on the information returned) later a Graphical timeline is built in the TAB based upon the information from the REST call.
My problem is how to make protractor wait for the REST call to be completed and the Timeline built before continuing to test the elements in the Timeline.
From various searches I am using the following code. I am just picking a single element on the Timeline to check for isPresent. I have also tried using browser.wait as opposed to ptor.getInstance however have the same problem that the wait is not waiting for the timeline to load fully. Any guidance would be much appreciated.
it('XXXXXX', function() {
var ptor = protractor.getInstance();
// Define element to wait for in the Timeline Graphic
var waitForElement = by.css('.timeline-time');
// Load the page
jobManagerPage.go();
// Click the inactive TAB to make active
jobManagerPage.eleDataVisTabLiTag.click();
// This is where I am expecting to wait for the element in the Timeline
// to be present before continuing
browser.wait(function() { return ptor.isElementPresent(waitForElement);
}, 8000);
// Test for the Timeline element to be present - this keeps failing !!!!!
expect(ptor.isElementPresent(waitForElement)).toBeTruthy();
});
One solution (though far from ideal) is to add an element to the DOM when you're loading, and remove it when done (or add/remove a CSS class, etc...). You may or may not have the opportunity to do that, depending on how your AJAX calls are being made.
I found this approach in an answer to this SO question: AngularJS + Protractor wait for all ajax calls to end / full page load, before running the tests
Hello I am trying to make a module that will make a popup window inside of SugarCRM when we receive a phone call. I have seen that some others have accomplished this already (expensive paid modules) and I am hoping to get some insight on the actual popup triggering part....
Our phone system has an API that sends an HTTP post to a URL when we have an incoming phone call.
Inside of SugarCRM, in my Modules code, I am not sure how I can use this HTTP POST from my Phone to do the Popup, the reason is I do not see how it can be fast enough, If I were to set a Cron job to check a page every 1 minute, that would still be too slow.
So does anyone have any ideas how the other similar Phone integration modules are doing it and having the Popup happen almost immediately as the phone call comes in?
Any ideas on how to do such a task? I am planning to do a Desktop application that just sits in the Tray and waits for the POST but seeing others have been able to get the same result inside of SugarCRM without a separate program really interests me.
I am working in a company that has created a expensive paid module to accomplished this, but I can give you hints for 2 ways to achieve this ;-)
1) With GenericHook
in custom/modules create a logic_hooks.php and a YOURCHOICEHERE.php
in the logic hooks create an after ui hook
$hook_array['after_ui_frame'] = Array();
$hook_array['after_ui_frame'][] = Array(1, 'Display Javascript for Telephone','custom/modules/YOURCHOICEHERE.php','GenericHooks', 'displayTelephoneJS');
and in YOURCHOICEHERE.php
class GenericHooks {
function displayTelephoneJS() {
if(!$_REQUEST['to_pdf']) echo '<div id=\"telephone_div\"></div>
<script type=\"text/javascript\" src=\"custom/somewherewhereyouwant/Telephone.js\"/></script>';
// you yould also add a stylesheet here
}
}
in the Telephone.js you can do what ever you want for example:
function Telephone_poll() {
$.post("some.php?poll=1,function(data){
if(data != 0)
{
var result= JSON.parse(data);
//HERE you can do manipulate your telephone_div and populate it with response data "result" from the call to some.php
$('#telephone_div').html("<span>HELLO<span>");
$('#telephone_div').show();
//Here you can also add styles and so on
}
setTimeout("Telephone_poll()", 1000); //restart the function every 1000ms
});
}
Telephone_poll(); //initial start of script
2) An other approach would be creating a demon/service from a php file that reruns itself.
Here you would need some way to identify users and Phones to ensure the popup is displayed for the correct user/phone.
I have the following setup on my site:
You enter credentials on a login page and that takes you to a second page (which normally produces no screen output) which validates the user and redirects them to the appropriate homepage.
My step definitions consist of three steps:
Load up initial login page.
Enter credentials and submit.
Verify (by checking page title) that I made it in the homepage.
My first step passes with flying colors.
My second step claims to pass.
My third step fails.
Upon review, I found that it's because the second step, while officially it didn't fail, didn't do what it was supposed to do. Zombie got stuck on the validation page. At first I thought it was just missing the redirect, but it seems that it doesn't execute ANYTHING on the validation page. I even commented out the entire page and simply put an output of "Hello" at the top of the page. If my browser.html(); can be believed, it doesn't even see that. I know I make it to the second page because I have
console.log("\n" + browser.location.href);
which shows me the URL of the second page.
I then have
console.log(browser.html());
which is empty.
I even have a:
browser.wait(10000,callback);
beforehand to give it some processing time but to no avail.
Some information that might be relevant:
This is a ColdFusion site. I know zombie's handling the concept of CF since it's loading the login page initially, although there's not much actual CF processing going on there.
There's DB access happening. If zombie is accessing like a regular browser, it shouldn't make a difference, but it's there. Although even when I comment everything out, it still doesn't work, so I doubt that's actually relevant.
This is my script portion for the login step. Please advise if I'm approaching this the wrong way.
this.When(/^I input my credentials$/, function(callback) {
browser.fill("login", "myusername").fill("password", "mypassword");
browser.document.forms[0].submit();
// Put in here to account for redirect time it will take to get past validation page to actual home page
browser.wait(10000,callback);
callback();
});
If you need any other information, please let me know. I would appreciate any help whatsoever in being able to make this work!
I am not sure I fully understand your problem, but it looks like this may be an issue with the way you are handling asynchronous calls. At any rate, you should not need to browser.wait for something like this at all. Try something like the following:
this.When(/^I input my credentials$/, function(callback) {
browser
.fill("login", "myusername")
.fill("password", "mypassword")
.pressButton("#selectorForYourButton", function (err) {
// Check for errors or any other behaviour this test is actually about
callback();
});
});
First, the pressButton method is preferable because it gets closer to testing actual browser interaction. But more importantly, callback() is only executed after all the events fired off by pressing the button have been resolved.
i am using GWT app engine to deploy my application in local host.
i want to redirect to second page when user completed his registration & clicked "submit" button, the browser has to redirect to automatically to his Profile page with his registration details.
i used fallowing code to redirect to second page from first page;
String url = GWT.getHostPageBaseURL()+"/UserViewProfile.html";
Window.Location.replace(url);
in my case the first page is URL is like:
http://127.0.0.1:8888/UserRegistration.html?gwt.codesvr=127.0.0.1:9997
when i submitted on "Submit" button it is edirecting to URL like:
http://127.0.0.1:8888/UserViewProfile.html
In second page(UserViewProfile.html) i developed simple HTML content & simple Textbox widget to check it's functionality. But i am seeing HTML content only but not "Textbox".
To see text box i has to type URL like:
http://127.0.0.1:8888/UserViewProfile.html?gwt.codesvr=127.0.0.1:9997
how i can access last part "?gwt.codesvr=127.0.0.1:9997" at end of my URL pattern automatically? if i add it manually, at the time of hosting it may leads to problem. please if any body give solution, that would be great.
I do not understand the use case. Anyway I guess you need to conditionally check if you are in DevMode or ProdMode, and add the gwt.codesvr=127.0.0.1:9997 query string accordingly. Something like:
String url = GWT.getHostPageBaseURL()+ "/UserViewProfile.html";
if (GWT.isProdMode()) {
Window.Location.replace(url);
} else {
Window.Location.replace(url + "?gwt.codesvr=127.0.0.1:9997");
}
The gwt.codesvr=127.0.0.1:9997 query string parameter is used by GWT to (simplifying) bootstrap your app in the so called Development Mode, instead of the Production Mode (the actual compiled version of your application). Without this check, if you are in DevMode, you end up requesting the UserViewProfile.html that looks for the compiled version of your app (that does not show anything, if you've never compiled it, or if you have simply recently clean the project).
Do also note that URL rewriting (by not simply changing the # fragment identifier), means application reloading.
I've got GWT module where I do some stuff and I have search results - doesn't matter in which form. Now after searching, and clicking on for example "Export to HTML" button,I would like to create new html page (for example from client side code by creating simple string which contains only listed results of searching list of results ) and open it in new browser window. I know that there is Window.open(...) method, but there I must specify url which i don't have. I want to create this new html page by client side - without server inference (I don't want to create some resource on server side and then paste url to this resource to client side). Is there any possibility to achieve this? If there is no option, other method which would satisfy me, is to open standard dialog box for saving, which will allow to save results in a html file.
Thanks for helps.
Kind regards.
Here's the code I use to print:
native void openPrintWindow(String contents) /*-{
var printWindow = window.open("", "PrintWin");
if (printWindow && printWindow.top) {
printWindow.document.write(contents);
printWindow.print();
printWindow.close();
} else {
alert("The print feature works by opening a popup window, but our popup window was blocked by your browser. If you can disable the blocker temporarily, you'll be able to print here. Sorry!");
}
}-*/;
Seems like you could adapt it for your purposes with some simple rewording and by removing the call to print()! The contents variable just holds flat HTML. There are no trips to the server.
openPrintWindow("<h1>Search Results</h1><ol><li>etc...");
The method of opening new window from client js which allows user to save that generated content from browser's save as menu is data:url scheme, content written to opened page via println usualy not saved. But data:url works only in morden browsers. And the content written should be quite small to fit browser's url length resteiction.
See example from this article http://en.wikipedia.org/wiki/Data_URI_scheme#JavaScript