var webPage = require('webpage');var page = webPage.create();console.log("Setting size to 'smartphone'...");page.viewportSize = { width: 320, height: 480 };page.open('http://uat1.travel.saga.co.uk',function(){setTimeout(function(){setTimeout(function(){console.log('Taking screenshot...');page.render('1.png');page.evaluate(function(){function eventFire(el, etype){  if (el.fireEvent) {    el.fireEvent('on' + etype);  } else {    var evObj = document.createEvent('Events');    evObj.initEvent(etype, true, false);    el.dispatchEvent(evObj);  }};eventFire($('#destinationInputControl')[0], 'click');});setTimeout(function(){setTimeout(function(){console.log('Taking screenshot...');page.render('2.png');page.evaluate(function(){$('#destinationSearchTextBox').val('Spain');});setTimeout(function(){setTimeout(function(){console.log("Testing whether 'Spain' is in markup...");var found = page.evaluate(function(){return $('body').text().search('Spain') > -1;});if (found === true) console.log('PASS');else console.log('FAIL');console.log("Testing whether 'Port of Span' is in markup...");var found = page.evaluate(function(){return $('body').text().search('Port of Span') > -1;});if (found === true) console.log('PASS');else console.log('FAIL');console.log("Testing whether 'Split' is in markup...");var found = page.evaluate(function(){return $('body').text().search('Split') > -1;});if (found === true) console.log('PASS');else console.log('FAIL');console.log('Taking screenshot...');page.render('3.png');phantom.exit();},3000);},1);},1000);},1);},5000);},1);});
var webPage = require('webpage');var page = webPage.create();console.log("Setting size to 'smartphone'...");page.viewportSize = { width: 320, height: 480 };page.open('http://uat1.travel.saga.co.uk',function(){console.log('Taking screenshot...');page.render('1.png');page.evaluate(function(){function eventFire(el, etype){  if (el.fireEvent) {    el.fireEvent('on' + etype);  } else {    var evObj = document.createEvent('Events');    evObj.initEvent(etype, true, false);    el.dispatchEvent(evObj);  }};eventFire($('#destinationInputControl')[0], 'click');});setTimeout(function(){setTimeout(function(){console.log('Taking screenshot...');page.render('2.png');phantom.exit();},1000);},1);});
Example #3
0
var listening = server.create().listen(8080, function(request, response) {

    var page = webpage.create();
    page.settings.loadImages = false;

    response.headers = {
        "Content-Type": "text/html; charset=UTF-8",
        "X-PhantomJS": "true"
    };

    page.onResourceRequested = function(requestData, request) {
        if (!/^https?:\/\/(www\.)?harlan\.com\.br/.test(requestData.url) || requestData.headers['Content-Type'] === 'text/css') {
            request.abort();
        }
    };

    if (request.url === "/") {
        page.open("https://www.harlan.com.br/development.html", "GET", function(status) {
            if (status !== 'success') {
                return onError(response, page);
            }

            waitfor(function() {
                return page.evaluate(function() {
                    if ($ === undefined) {
                        return false;
                    }
                    return $(".site").length;
                });
            }, function() {
                onSuccess(response, page, "site");
            }, function() {
                onError(response, page);
            }, 10000);
        });

        return;
    }

    page.open("https://www.harlan.com.br/" + request.url, "GET", function(status) {
        if (status !== 'success') {
            return onError(response, page);
        }

        waitfor(function() {
            return page.evaluate(function() {

                if (window.harlan === undefined) {
                    return false;
                }

                if (window.pageLoaded === undefined) {
                    window.pageLoaded = false;
                }

                if (window.registered === undefined) {
                    window.harlan.registerTrigger("seo::ready", function(args, callback) {
                        window.pageLoaded = true; /* GLOBAL */
                        callback();
                    }); /* Harlan Global */
                    window.registered = true;
                }

                return window.pageLoaded || $(".result").length > 0;
            });
        }, function() {
            onSuccess(response, page, "app");
        }, function() {
            onError(response, page);
        }, 15000);
    });
});
Example #4
0
function convert(source, dest, scale) {
    var page = webpage.create();

    page.onLoadFinished = function (status) {
        if (status !== "success") {
            console.error("Unable to load the source file.");
            phantom.exit();
            return;
        }

        var dimensions = getSvgDimensions(page);
        var width = Math.round(dimensions.width * scale);
        var height = Math.round(dimensions.height * scale);
        page.viewportSize = {
            width: width,
            height: height
        };
        page.clipRect = { 
            top: 0,
            left: 0,
            width: width,
            height: height
        };
        
        page.evaluate(function (width, height) {
            var img = document.getElementsByTagName("img")[0];
            img.setAttribute("width", width);
            img.setAttribute("height", height);
        }, width, height);

        if (!dimensions.usesViewBox) {
            page.zoomFactor = scale;
        }



        // This delay is I guess necessary for the resizing to happen?
        setTimeout(function () {
            page.render(dest);
            phantom.exit();
        }, 0);
    }

    var content = fs.read(source);

    var html = "\
    <!doctype html>\
    <html>\
        <head>\
            <style>\
                * { padding: 0; margin: 0; }\
                img { display: block; }\
                svg { display: none; }\
            </style>\
        </head>\
        <body>\
            <img src=\"data:image/svg+xml;base64," + btoa(content) + "\" width=\"400\" height=\"300\" />\
            " + content + "\
        </body>\
    </html>\
    ";

    var url = "index.html";

    page.setContent(html, url);
}
Example #5
0
controlpage.onAlert=function(msg){
	var request=JSON.parse(msg);
	var cmdId=request[1];
//	console.log(request);
	if(request[0]===0){
		switch(request[2]){
		case 'createPage':
			var id=pageId++;
			var page=webpage.create();
			pages[id]=page;
			setupPushNotifications(id, page);
			respond([id,cmdId,'pageCreated']);
			break;
		case 'injectJs':
			var success=phantom.injectJs(request[3]);
			respond([0,cmdId,'jsInjected',success]);
			break;
        case 'addCookie':
            phantom.addCookie(request[3]);
            respond([0,cmdId,'cookieAdded',success]);
            break;
		case 'exit':
			respond([0,cmdId,'phantomExited']);	//optimistically to get the response back before the line is cut
			break;
		case 'exitAck':
			phantom.exit();
			break;
		default:
			console.error('unrecognized request:'+request);
			break;
		}
	}
	else{
		var id=request[0];
		var page=pages[id];
		switch(request[2]){
		case 'pageOpen':
			page.open(request[3]);
			break;
		case 'pageOpenWithCallback':
			page.open(request[3], function(status){
				respond([id, cmdId, 'pageOpened', status]);
			});
			break;
		case 'pageClose':
			page.close();
			respond([id,cmdId,'pageClosed']);
			break;
		case 'pageInjectJs':
			var result=page.injectJs(request[3]);
			respond([id,cmdId,'pageJsInjected',JSON.stringify(result)]);
			break;
		case 'pageIncludeJs':
			page.includeJs(request[3]);
			respond([id,cmdId,'pageJsIncluded']);
			break;
		case 'pageSendEvent':
			page.sendEvent(request[3],request[4],request[5]);
			respond([id,cmdId,'pageEventSent']);
			break;
		case 'pageUploadFile':
			page.uploadFile(request[3],request[4]);
			respond([id,cmdId,'pageFileUploaded']);
			break;
		case 'pageEvaluate':
			var result=page.evaluate.apply(page,request.slice(3));
			respond([id,cmdId,'pageEvaluated',JSON.stringify(result)]);
			break;
        case 'pageEvaluateAsync':
			page.evaluateAsync.apply(page,request.slice(3));
			respond([id,cmdId,'pageEvaluatedAsync']);
			break;
		case 'pageRender':
			page.render(request[3]);
			respond([id,cmdId,'pageRendered']);
			break;
		case 'pageRenderBase64':
			var result=page.renderBase64(request[3]);
			respond([id,cmdId,'pageRenderBase64Done', result]);
			break;
		case 'pageSet':
			page[request[3]]=request[4];
			respond([id,cmdId,'pageSetDone']);
			break;
		case 'pageGet':
			var result=page[request[3]];
			respond([id,cmdId,'pageGetDone',JSON.stringify(result)]);
			break;
		case 'pageSetFn':
			page[request[3]] = eval('(' + request[4] + ')')
			break;
		default:
			console.error('unrecognized request:'+request);
			break;
		}
	}
	//console.log('command:'+parts[1]);
	return;
};
Example #6
0
intervalout = setInterval(function(){
	//line++;
   // system.stdout.writeLine('ddddd '+line);
   mbl=false;
   if(state==0){
   		readdata=  system.stdin.readLine();   
	   if(readdata!=""){
	   		state=1;
	   		if(jxdata(readdata)==true){
		   			timecount=0;
		   			mbl=true;
		   			returl="";
		   			rettitle="";
		   			txt="";
		   			retotherdata="";
	   		}
	   		else{
	   			state=0;	
	   		}
	   }
	}

   if(mbl==true){
   		txt="";   		
   		mbl=false;	
   		//console.log(functxt);
   	//	console.log(wfunctxt);
		Func=new Function(functxt);  
		func=new Func();
		wFunc=new Function(wfunctxt);
		wfunc=new wFunc();	 
   		//console.log("action:"+action);		
			//console.log("-------action:"+action);	
	    if(action==0){
	    	if(page!=null)
				page.close();
			//console.log("----page.close();------------------------------------------------");			
	   		page=page1.create();
		    page.onLoadFinished=loadend;
		}
		switch(action)
		{
			case 0:
				if(wurl!=""){ 
		   			wurl=wfunc.GetWUrl(wurl); 
				  	//console.log("processdata();");				   			
		   			processdata();
		   			//wurl="";
	   			}
			break;
			case 1:

				if(func.Startaction(page)==""){
					state=4;
				}
				  
			break;	
		}
	}else
	{
		timecount++;
		if(timecount== wtout)//wtout没有完成重读数据
		{	
			state=4;
		}
	}

}, waittime);
Example #7
0
	createPage: function () {
		var page  = webpage.create();
		var id = setup_page(page);
		return { page_id: id };
	},
Example #8
0
test(function () {
    var defaultPage = webpage.create();
    assert_deep_equals(defaultPage.scrollPosition, {left:0,top:0});
}, "default scroll position");
Example #9
0
/**
 * PhantomJS Test Script
 */

var webPage = require('webpage');

var page1 = webPage.create();
var page2 = webPage.create();
var page3 = webPage.create();

function shouldBeEqual(arg1, arg2) {
    if (arg1 === arg2) {
        console.log(arg1, '===', arg2, 'ok');
    } else {
        console.log(arg1, '!==', arg2, 'test failed');
        phantom.exit();
    }
}

page1.open('test/phantom.tab.html', function () {

    var title1 = page1.evaluate(function () {
        return document.title;
    });

    shouldBeEqual(/master/i.test(title1), true);

    page2.open('test/phantom.tab.html', function () {

        page3.open('test/phantom.tab.html', function () {
Example #10
0
test(function () {
    var defaultPage = webpage.create();
    assert_deep_equals(defaultPage.clipRect, {height:0,left:0,top:0,width:0});
}, "default page.clipRect");
Example #11
0
function createNewPage( dimensions ) {
  var page = webpage.create();
  if( dimensions ) setDimensions( page, dimensions );
  return page;
}
Example #12
0
        load: function (config, task, scope) {
            var page = WebPage.create(),
                pagetemp = WebPage.create(),
                event;

            if (config.userAgent && config.userAgent != "default") {
                if (config.userAgentAliases[config.userAgent]) {
                    config.userAgent = config.userAgentAliases[config.userAgent];
                }
                page.settings.userAgent = config.userAgent;
            }
            ['onInitialized', 'onLoadStarted', 'onResourceRequested', 'onResourceReceived']
                .forEach(function (event) {
                if (task[event]) {
                    page[event] = function () {
                        var args = [page, config],
                            a, aL;
                        for (a = 0, aL = arguments.length; a < aL; a++) {
                            args.push(arguments[a]);
                        }
                        task[event].apply(scope, args);
                    };

                }
            });
            if (task.onLoadFinished) {
                page.onLoadFinished = function (status) {
                    if (config.wait) {
                        setTimeout(
                            function () {
                                task.onLoadFinished.call(scope, page, config, status);
                            },
                            config.wait
                        );
                    } else {
                        task.onLoadFinished.call(scope, page, config, status);
                    }
                    phantom.exit();

                    page = WebPage.create();
                    doPageLoad();
                };
            } else {
                page.onLoadFinished = function (status) {
                    phantom.exit();
                };
            }
            page.settings.localToRemoteUrlAccessEnabled = true;
            page.settings.webSecurityEnabled = false;
            page.onConsoleMessage = function (msg) {
                console.log(msg)
                if (msg.indexOf('jserror-') >= 0){
                    loadreport.performance.evalConsoleErrors.push(msg.substring('jserror-'.length,msg.length));
                }else{
                    if (msg.indexOf('loading-') >= 0){
                        loadreport.performance.evalConsole.loading = msg.substring('loading-'.length,msg.length);
                    } else if (msg.indexOf('interactive-') >= 0){
                        loadreport.performance.evalConsole.interactive = msg.substring('interactive-'.length,msg.length);
                    // } else if (msg.indexOf('complete-') >= 0){
                    //     loadreport.performance.evalConsole.complete = msg.substring('complete-'.length,msg.length);
                    } else if (msg.indexOf('onload-') >= 0){
                        loadreport.performance.evalConsole.onload = msg.substring('onload-'.length,msg.length);
                    }
                    //loadreport.performance.evalConsole.push(msg);
                }
            };

            page.onError = function (msg, trace) {
                //console.log("+++++  " + msg);
                trace.forEach(function(item) {
                    loadreport.performance.evalConsoleErrors.push(msg + ':' + item.file + ':' + item.line);
                })
            };

            function doPageLoad(){
                setTimeout(function(){page.open(config.url);},config.cacheWait);
            }

            if(config.task == 'performancecache'){

                pagetemp.open(config.url,function(status) {
                    if (status === 'success') {
                        pagetemp.release();
                        doPageLoad();
                    }
                });
            }else{
                doPageLoad();
            }
        },
Example #13
0
/**
 * create webpage and bind events
 * @param {string} url
 * @param {Object} options
 * @param {Function} onload
 */
function createPage(url, options, onload){
    var page = webpage.create();

    // remove application cache db
    // @see https://github.com/fouber/page-monitor/issues/3
    if(options.cleanApplicationCache){
        var path = page.offlineStoragePath + '/ApplicationCache.db';
        if(fs.isFile(path)){
            if(fs.remove(path) === false){
                log('unable to remove application cache [' + path + ']', _.log.WARNING);
            } else {
                log('removed application cache [' + path + ']');
            }
        }
    }

    var timer, count = 0,
        delay = options.render.delay;
    var callback = function(){
        clearTimeout(timer);
        if(count === 0){
            timer = setTimeout(function(){
                if(onload(page) !== false){
                    phantom.exit();
                }
                callback = function(){};
            }, delay);
        }
    };
    settings(page, options.page);
    page.onLoadStarted = function(){
        if(page.url !== 'about:blank'){
            count++;
            //console.log('* [' + count + ']' + page.url);
            callback();
        }
    };
    page.onloadFinished = function(status){
        if(status === 'success'){
            callback();
        } else {
            log('load page error [' + status + ']', _.log.ERROR);
            phantom.exit(1);
        }
    };
    page.onResourceRequested = function(req){
        count++;
        // console.log('+ [' + count + ']' + req.url);
        callback();
    };
    page.onResourceReceived = function(res){
        if(res.stage === 'end'){
            count--;
            // console.log('- [' + count + ']' + res.url);
            callback();
        }
    };
    page.onResourceTimeout = function(req){
        count--;
        log('resource [' + req.url + '] timeout', _.log.WARNING);
        callback();
    };
    page.onError = function(msg, trace){
        var msgStack = [ msg ];
        if (trace && trace.length) {
            msgStack.push('TRACE:');
            trace.forEach(function(t) {
                msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
            });
        }
        log(msgStack.join('\n'), _.log.ERROR);
    };
    page.onInitialized = function() {
        if(options.events){
            evaluate(page, options.events.init);
        }
    };
    page.onConsoleMessage = function(msg){
        if(msg.substring(0, TOKEN.length) === TOKEN){
            log(msg.substring(TOKEN.length));
        } else {
            log(msg, _.log.NOTICE);
        }
    };
    page.open(url);
    return page;
}
Example #14
0
  }, function (request, response) {
    phantom.clearCookies();

    //console.debug(JSON.stringify(request, null, 4));
    // check method
    if (request.method == 'GET') {
      body = "method not allowed!";
      response.statusCode = 403;
      response.headers = {
        'Cache': 'no-cache',
        'Content-Length': body.length
      };
      response.write(body);
      response.closeGracefully();
      return;
    }
    
    var first_response = null,
        finished = false,
        page_loaded = false,
        start_time = Date.now(),
        end_time = null,
        script_executed = false,
        script_result = null;

    var fetch = JSON.parse(request.postRaw);
    console.debug(JSON.stringify(fetch, null, 2));

    // create and set page
    var page = webpage.create();
    page.onConsoleMessage = function(msg) {
        console.log('console: ' + msg);
    };
    page.viewportSize = {
      width: fetch.js_viewport_width || 1024,
      height: fetch.js_viewport_height || 768*3
    }
    if (fetch.headers && fetch.headers['User-Agent']) {
      page.settings.userAgent = fetch.headers['User-Agent'];
    }
    // this may cause memory leak: https://github.com/ariya/phantomjs/issues/12903
    page.settings.loadImages = fetch.load_images === undefined ? true : fetch.load_images;
    page.settings.resourceTimeout = fetch.timeout ? fetch.timeout * 1000 : 120*1000;
    if (fetch.headers) {
      page.customHeaders = fetch.headers;
    }

    // add callbacks
    page.onInitialized = function() {
      if (!script_executed && fetch.js_script && fetch.js_run_at === "document-start") {
        script_executed = true;
        console.log('running document-start script.');
        script_result = page.evaluateJavaScript(fetch.js_script);
      }
    };
    page.onLoadFinished = function(status) {
      page_loaded = true;
      if (!script_executed && fetch.js_script && fetch.js_run_at !== "document-start") {
        script_executed = true;
        console.log('running document-end script.');
        script_result = page.evaluateJavaScript(fetch.js_script);
      }
      console.debug("waiting "+wait_before_end+"ms before finished.");
      end_time = Date.now() + wait_before_end;
      setTimeout(make_result, wait_before_end+10, page);
    };
    page.onResourceRequested = function(request) {
      console.debug("Starting request: #"+request.id+" ["+request.method+"]"+request.url);
      end_time = null;
    };
    page.onResourceReceived = function(response) {
      console.debug("Request finished: #"+response.id+" ["+response.status+"]"+response.url);
      if (first_response === null && response.status != 301 && response.status != 302) {
        first_response = response;
      }
      if (page_loaded) {
        console.debug("waiting "+wait_before_end+"ms before finished.");
        end_time = Date.now() + wait_before_end;
        setTimeout(make_result, wait_before_end+10, page);
      }
    }
    page.onResourceError = page.onResourceTimeout=function(response) {
      console.info("Request error: #"+response.id+" ["+response.errorCode+"="+response.errorString+"]"+response.url);
      if (first_response === null) {
        first_response = response;
      }
      if (page_loaded) {
        console.debug("waiting "+wait_before_end+"ms before finished.");
        end_time = Date.now() + wait_before_end;
        setTimeout(make_result, wait_before_end+10, page);
      }
    }

    // make sure request will finished
    setTimeout(function(page) {
      make_result(page);
    }, page.settings.resourceTimeout + 100, page);

    // send request
    page.open(fetch.url, {
      operation: fetch.method,
      data: fetch.data,
    });

    // make response
    function make_result(page) {
      if (finished) {
        return;
      }
      if (Date.now() - start_time < page.settings.resourceTimeout) {
        if (!!!end_time) {
          return;
        }
        if (end_time > Date.now()) {
          setTimeout(make_result, Date.now() - end_time, page);
          return;
        }
      }

      var result = {};
      try {
        result = _make_result(page);
      } catch (e) {
        result = {
          orig_url: fetch.url,
          status_code: 599,
          error: e.toString(),
          content:  '',
          headers: {},
          url: page.url,
          cookies: {},
          time: (Date.now() - start_time) / 1000,
          save: fetch.save
        }
      }

      page.close();
      finished = true;
      console.log("["+result.status_code+"] "+result.orig_url+" "+result.time)

      var body = JSON.stringify(result, null, 2);
      response.writeHead(200, {
        'Cache': 'no-cache',
        'Content-Type': 'application/json',
      });
      response.write(body);
      response.closeGracefully();
    }

    function _make_result(page) {
      var cookies = {};
      page.cookies.forEach(function(e) {
        cookies[e.name] = e.value;
      });

      var headers = {};
      if (first_response.headers) {
        first_response.headers.forEach(function(e) {
          headers[e.name] = e.value;
        });
      }

      return {
        orig_url: fetch.url,
        status_code: first_response.status || 599,
        error: first_response.errorString,
        content:  page.content,
        headers: headers,
        url: page.url,
        cookies: cookies,
        time: (Date.now() - start_time) / 1000,
        js_script_result: script_result,
        save: fetch.save
      }
    }
  });
'use strict';

var system = require('system'),
    webpage = require('webpage').create,
    page = webpage();

if (!system.args[1]) {
    console.log('Usage: %s url [device_type]', system.args[0]);
    phantom.exit(1);
}

var url = system.args[1],
    device_type = system.args[2];

// http://whatsmyuseragent.com/Devices/iPhone-User-Agent-Strings
var user_agents = {
    'iphone': 'Mozilla/5.0(iPhone;U;CPUiPhoneOS4_0likeMacOSX;en-us)AppleWebKit/532.9(KHTML,likeGecko)Version/4.0.5Mobile/8A293Safari/6531.22.7',
    'ipad': 'Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10'
};

if (device_type in user_agents) {
    page.settings.userAgent = user_agents[device_type];
}

page.onError = function () {};

page.open(url);

page.onLoadFinished = function () {
    setTimeout(function () {
        var report_suite_id = page.evaluate(function () {
Example #16
0
function renderUrl(url, output, options) {
  options = options || {};

  var statusCode,
      page = webpage.create();

  for (var k in options) {
    if (options.hasOwnProperty(k)) {
      page[k] = options[k];
    }
  }

  // determine the statusCode
  page.onResourceReceived = function (resource) {
    if (resource.url == url) {
      console.log('response: ' + JSON.stringify(resource))
      statusCode = resource.status;
    }
  };

  page.onResourceError = function (resourceError) {
    // Log the error but allow normal "Unable to load the page." handling to occur too so that we
    // can get and report the actual HTTP status code. (resourceError.errorCode just returns a code
    // from http://doc.qt.io/qt-4.8/qnetworkreply.html#NetworkError-enum)
    console.log(resourceError.errorString);
  };

  if (redirects_num > 0) {
    page.onNavigationRequested = function (redirect_url, type, willNavigate, main) {
      if (main) {
        if (redirect_url !== url) {
          page.close();

          if (redirects_num-- >= 0) {
            renderUrl(redirect_url, output, options);
          } else {
            error(url + ' redirects to ' + redirect_url + ' after maximum number of redirects reached');
          }
        }
      }
    };
  }

  page.open(url, function (status) {
    if (status !== 'success' || (statusCode != 200 && statusCode != null)) {
      if (fs.exists(output)) {
        fs.remove(output);
      }
      try {
        fs.touch(output);
      } catch (e) {
        console.log(e);
      }

      error('Unable to load the page. (HTTP ' + statusCode + ') (URL: ' + url + ')');
    } else {
     /* Check whether the loaded page overwrites the header/footer setting,
        i.e. whether a PhantomJSPriting object exists. Use that then instead
        of our defaults above.
        See https://github.com/ariya/phantomjs/blob/master/examples/printheaderfooter.js#L66
      */
      window.setTimeout(function () {
        if (page.evaluate(function(){return typeof PhantomJSPrinting == "object";})) {
          paperSize = page.paperSize;
          paperSize.header.height = page.evaluate(function() {
            return PhantomJSPrinting.header.height;
          });
          paperSize.header.contents = phantom.callback(function(pageNum, numPages) {
            return page.evaluate(function(pageNum, numPages){return PhantomJSPrinting.header.contents(pageNum, numPages);}, pageNum, numPages);
          });
          paperSize.footer.height = page.evaluate(function() {
            return PhantomJSPrinting.footer.height;
          });
          paperSize.footer.contents = phantom.callback(function(pageNum, numPages) {
            return page.evaluate(function(pageNum, numPages){return PhantomJSPrinting.footer.contents(pageNum, numPages);}, pageNum, numPages);
          });
          page.paperSize = paperSize;
        }
        page.render(output);
        console.log('rendered to: ' + output, new Date().getTime());
        phantom.exit();
      }, render_time);
    }
  });
}
Example #17
0
function renderUrl(url, output, options) {
  options = options || {};

  var statusCode,
      page = webpage.create();

  for (var k in options) {
    if (options.hasOwnProperty(k)) {
      page[k] = options[k];
    }
  }

  // determine the statusCode
  page.onResourceReceived = function (resource) {
    if (resource.url == url) {
      statusCode = resource.status;
    }
  };

  page.onResourceError = function (resourceError) {
    // Do not fail on missing resource
    // error(resourceError.errorString + ' (URL: ' + resourceError.url + ')');
  };

  page.onNavigationRequested = function (redirect_url, type, willNavigate, main) {
    if (main) {
      if (redirect_url !== url) {
        page.close();

        if (redirects_num-- >= 0) {
          renderUrl(redirect_url, output, options);
        } else {
          error(url + ' redirects to ' + redirect_url + ' after maximum number of redirects reached');
        }
      }
    }
  };

  page.open(url, function (status) {
    if (status !== 'success' || (statusCode != 200 && statusCode != null)) {
      if (fs.exists(output)) {
        fs.remove(output);
      }
      try {
        fs.touch(output);
      } catch (e) {
        console.log(e);
      }

      error('Unable to load the URL: ' + url + ' (HTTP ' + statusCode + ')');
    } else {
      window.setTimeout(function () {
        page.render(output + '_tmp.pdf');

        if (fs.exists(output)) {
          fs.remove(output);
        }

        try {
          fs.move(output + '_tmp.pdf', output);
        } catch (e) {
          error(e);
        }
        console.log('Rendered to: ' + output, new Date().getTime());
        phantom.exit(0);
      }, render_time);
    }
  });
}
function dumpClassTable(providerInfo, // all info about the HTML page
    studioId, // studio number with the provider
    redirectPage, // optional extra redirect to use if page is weird
    numRetries, // how many more times to try scraping
    timeout, // how long to wait to reload, incremented with each retry
    verbose) // extra printing
{
  const URL = providerInfo.urlPattern + studioId;

  var studiopage = webpage.create();
  var tablepage = webpage.create();

  var needsTableResource = (providerInfo.tableResourcePattern !== null);
  var tableresource = null;
  var redirectedToTable = false;
  var redirected = false;

  /* For really verbose debugging
  tablepage.onConsoleMessage = function(msg, lineNum, sourceId) {
    console.trace(msg);
  }

  studiopage.onLoadStarted = function() {
    console.trace('= onLoadStarted()');
    var currentUrl = studiopage.evaluate(function() {
      return window.location.href;
    });
    console.trace('  leaving url: ' + currentUrl);
  };

  studiopage.onNavigationRequested = function(url, type, willNavigate, main) {
    console.trace('= onNavigationRequested');
    console.trace('  destination_url: ' + url);
    console.trace('  type (cause): ' + type);
    console.trace('  will navigate: ' + willNavigate);
    console.trace('  from webpage\'s main frame: ' + main);
  };

  studiopage.onResourceRequested = function (request) {
    console.trace('= onResourceRequested()');
    console.trace('  request: ' + JSON.stringify(request, undefined, 4));
  };
  */

  var ALL_LOCATIONS_INDEX = 0;

  dumpPageTimeout = null;
  tablepage.onLoadFinished = function(status) {
    if (status === 'success')
    {
      // Use a timeout here because iframes all trigger "onLoadFinished" again
      if (verbose) {
        console.log('Finished loading table resource');
      }

      if (dumpPageTimeout === null)
      {
        dumpPageTimeout = setTimeout(function(){
          var locationChanged = tablepage.evaluate(function(locationCssId, ALL_LOCATIONS_INDEX){
            var locationDropdown = document.querySelector(locationCssId);
            var changed = false;
            if (locationDropdown !== null &&
                locationDropdown.selectedIndex !== ALL_LOCATIONS_INDEX)
            {
              locationDropdown.selectedIndex = ALL_LOCATIONS_INDEX;
              locationDropdown.onchange();
              changed = true;
            }
            return changed;
          }, providerInfo.locationCssId, ALL_LOCATIONS_INDEX);
          if (verbose) {
            console.trace('Changed location: [' + locationChanged + ']');
          }

          setTimeout(function() {
            var viewChanged = tablepage.evaluate(function(viewModeCssId, selectedViewModeCssId){
              var correctView = document.querySelector(selectedViewModeCssId);
              console.log(correctView);
              if (correctView !== null && correctView !== undefined)
              {
                return false;
              }
              else
              {
                var viewMode = document.querySelector(viewModeCssId);
                console.log(viewMode);
                viewMode.click();
                return true;
              }
            }, providerInfo.viewModeCssId, providerInfo.selectedViewModeCssId);

            if (verbose) {
              console.trace('Changed view mode: [' + viewChanged + ']');
            }

            setTimeout(function(){
              // The execution of "evaluate" is sandboxed, so pass in extra 
              // parameters from the outside.
              var tableElement = tablepage.evaluate(function(tableCssClass) {
                return document.querySelector(tableCssClass);
              }, providerInfo.tableCssClass);
              var path = Math.abs(studioId) + '.html';
              if (tableElement.outerHTML === '')
              {
                if (numRetries > 0)
                {
                  if (verbose) {
                    console.error('No html found, retrying [' + path + ']');
                  }
                  studiopage.close();
                  tablepage.close();
                  dumpClassTable(providerInfo,
                      studioId,
                      redirectPage,
                      timeout + DEFAULT_TIMEOUT_INCREMENT,
                      numRetries - 1,
                      verbose);
                }
                else
                {
                  if (verbose) {
                    console.error('No html found, done trying [' + path + ']');
                  }
                  studiopage.close();
                  tablepage.close();
                  phantom.exit();
                }
              }
              else
              {
                fs.write(path, tableElement.outerHTML, function(error) {
                  if (error) {
                    console.error('Error writing: ' + error.message);
                  } else {
                    console.error('Success writing: ' + error.message);
                  }
                });
                tablepage.close();
                phantom.exit();
              }
            }, viewChanged ? timeout : 0);
          }, locationChanged ? timeout : 0);
        }, timeout);
      }
    }
  }

  studiopage.onResourceReceived = function(response) {
    if (needsTableResource &&
        response.stage === "end" &&
        response.url.match(providerInfo.tableResourcePattern))
    {
      if (verbose) {
        console.trace('= onResourceReceived()' );
        console.trace('  id: ' + response.id + ', stage: "' + response.stage + '", url: ' + response.url);
        console.trace('Will get table resource: ' + response.url);
      }
      tableresource = response.url;
    }
  };

  studiopage.onLoadFinished = function(status) {
    if (verbose) {
      console.trace('= onLoadFinished()');
      console.trace('  status: ' + status);
      var currentUrl = studiopage.evaluate(function() {
        return window.location.href;
      });
      console.trace('  url: ' + currentUrl);
    }
    if (status === 'success')
    {
      if (redirectPage !== '' && redirected === false)
      {
        tableresource = null;
        redirected = true;
        studiopage.open(redirectPage);
      }

      if (needsTableResource)
      {
        if (redirectedToTable === false)
        {
          if (tableresource === null)
          {
            if (verbose) {
              console.trace('Table resource not found, forcing redirect');
            }
            studiopage.open(providerInfo.forcePage);
          }
          else
          {
            if (verbose) {
              console.trace('Successful load, now requesting table resource');
            }
            redirectedToTable = true;
            tablepage.open(tableresource);
            studiopage.close();
          }
        }
      }
      else
      {
        if (verbose) {
          console.trace('Successful load of page, getting table');
        }
        var tableElement = studiopage.evaluate(function(tableCssClass) {
          return document.querySelector(tableCssClass);
        }, providerInfo.tableCssClass);
        var path = Math.abs(studioId) + '.html';
        fs.write(path, tableElement.outerHTML, function(error) {
          if (error) {
            if (verbose) {
              console.error("Error writing:  " + error.message);
            }
          } else {
            if (verbose) {
              console.log("Success writing to " + path);
            }
          }
        });
        studiopage.close();
        phantom.exit();
      }
    }
    else
    {
      if (verbose) {
        console.error('Error loading studio page');
      }
    }
  };

  studiopage.onResourceError = function(resourceError) {
    //console.trace('= onResourceError()');
    //console.trace('  - unable to load url: "' + resourceError.url + '"');
    //console.trace('  - error code: ' + resourceError.errorCode + ', description: ' + resourceError.errorString );
  };

  studiopage.onError = function(msg, trace) {
    //console.error('= onError()');
    var msgStack = ['  ERROR: ' + msg];
    if (trace) {
      msgStack.push('  TRACE:');
      trace.forEach(function(t) {
        msgStack.push('    -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));
      });
    }
    //console.error(msgStack.join('\n'));
  };

  studiopage.open(URL);
}
Example #19
0
File: pdf.js Project: RickyCook/CV
const system = require('system')
const webpage = require('webpage')

const renderEnv = system.args[1]

const page = webpage.create()
page.paperSize = 'A4'
page.open(renderEnv + '.html', function(status) {
    page.render(renderEnv + '.pdf')
    phantom.exit()
})
Example #20
0
    loadTask: function (taskName, config, scope, done) {
        var task = loadreport[taskName];
        var page = WebPage.create();

        // console.log(JSON.stringify(config))

        if (config.viewportSize) {

            var size = config.viewportSize;
            page.viewportSize = size;
            page.clipRect = { left: 0, top: 0, width: size.width, height: size.height };
        }

        // if (config.retina) {
        //     page.zoomFactor = 0.5;
        // }
        
        if (config.cookie){
            page.addCookie(config.cookie);
        }
        
        if (config.customHeaders) {
            page.customHeaders = config.customHeaders;
        }

        if (config.userAgent && config.userAgent != "default") {
            if (config.userAgentAliases[config.userAgent]) {
                config.userAgent = config.userAgentAliases[config.userAgent];
            }
            page.settings.userAgent = config.userAgent;
        }

        ['onInitialized', 'onLoadStarted', 'onResourceRequested', 'onResourceReceived']
            .forEach(function (event) {
            if (task[event]) {
                page[event] = function () {
                    var args = [page, config],
                        a, aL;
                    for (a = 0, aL = arguments.length; a < aL; a++) {
                        args.push(arguments[a]);
                    }
                    task[event].apply(scope, args);
                };

            }
        });

        page.onLoadFinished = function (status) {
            if (config.wait) {
                setTimeout( function () {
                        task.onLoadFinished.call(scope, page, config, status, done);
                }, config.wait);
            } else {
                task.onLoadFinished.call(scope, page, config, status, done);
            }
        };

        page.settings.localToRemoteUrlAccessEnabled = true;
        page.settings.webSecurityEnabled = false;
        page.onConsoleMessage = function (msg, lineNum, sourceId) {

            console.log('CONSOLE: ' + msg);

            if (msg.indexOf('jserror-') >= 0){
                loadreport.performance.evalConsoleErrors.push(msg.substring('jserror-'.length,msg.length));
            }else{
                if (msg.indexOf('loading-') >= 0){
                    loadreport.performance.evalConsole.loading = msg.substring('loading-'.length,msg.length);
                } else if (msg.indexOf('interactive-') >= 0){
                    loadreport.performance.evalConsole.interactive = msg.substring('interactive-'.length,msg.length);
                // } else if (msg.indexOf('complete-') >= 0){
                //     loadreport.performance.evalConsole.complete = msg.substring('complete-'.length,msg.length);
                } else if (msg.indexOf('onload-') >= 0){
                    loadreport.performance.evalConsole.onload = msg.substring('onload-'.length,msg.length);
                }
                //loadreport.performance.evalConsole.push(msg);
            }
        };

        page.onError = function (msg, trace) {
            var msgStack = ['ERROR: ' + msg];
            if (trace && trace.length) {
                msgStack.push('TRACE:');
                trace.forEach(function(t) {
                    msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));
                });
            }
            console.error(msgStack.join('\n'));
            
            trace.forEach(function(item) {
                loadreport.performance.evalConsoleErrors.push(msg + ':' + item.file + ':' + item.line);
            })
        };

        // console.log(JSON.stringify(config, undefined, 4))

        if(taskName == 'performancecache'){
            var pagetemp = WebPage.create();
            pagetemp.open(config.url,function(status) {
                if (status === 'success') {
                    pagetemp.close();
                    setTimeout(function(){page.open(config.url)}, config.cacheWait);
                }
            });
        }else{
            page.open(config.url);
        }
    },
Example #21
0
var webPage = require('webpage');
var page = webPage.create();



var system = require('system');

var args = system.args;

page.open('https://m.taobao.com', function(status) {

    setTimeout(function() {


        var cookies = page.cookies;

        // window.localStorage


        console.log(JSON.stringify(localStorage));

        // console.log(JSON.stringify(cookies));

        for (var i in cookies) {
            console.log(i + '****' + cookies[i].name + '=' + cookies[i].value + '*****domain ==' + cookies[i].domain);
        }
        phantom.exit();

    }, 2000)

});
Example #22
0
/* global document */

/*
 * grunt-photoBox
 * https://github.com/stefan/grunt-photoBox
 *
 * Copyright (c) 2013 stefan judis
 * Licensed under the MIT license.
 */



var system        = require ( 'system' ),
    webpage       = require( 'webpage' ),
    fs            = require( 'fs' ),
    page          = webpage.create(),
    picture       = system.args[ 1 ],
    split         = picture.split( '#' ),
    url           = split[ 0 ],
    width         = +split[ 1 ],
    image         = split[ 2 ],
    indexPath     = system.args[ 2 ],
    settings      = fs.read( indexPath + 'options.json' );

if ( settings !== '{}' ) {
  try {
    system.stderr.writeLine( 'Read settings: ' + settings );
    settings = JSON.parse( settings );

    page.settings = settings;
  } catch( e ) {
Example #23
0
//Released to the public domain.

var port=phantom.args[0];
var webpage=require('webpage');
var controlpage=webpage.create();


function respond(response){
//	console.log('responding:'+response);
	controlpage.evaluate('function(){socket.emit("res",'+JSON.stringify(response)+');}');
}

var pages={};
var pageId=1;

function setupPushNotifications(id, page) {
	var callbacks=['onAlert','onConfirm','onConsoleMessage','onError','onInitialized','onLoadFinished',
				   'onLoadStarted','onPrompt','onResourceRequested','onResourceReceived','onUrlChanged',
				   'onCallback'];
	function push(notification){
		controlpage.evaluate('function(){socket.emit("push",'+JSON.stringify(notification)+');}');
	}
	callbacks.forEach(function(cb) {
		page[cb]=function(parm){
			var notification=Array.prototype.slice.call(arguments);
			if((cb==='onResourceRequested')&&(parm.url.indexOf('data:image')===0)) return;

			push([id, cb, notification]);
		};
	})
}
var loop = function() {
	var line = system.stdin.readLine();
	if (!line.trim()) {
		fs.remove(filename);
		return phantom.exit(0);
	}

	try {
		line = JSON.parse(line);
	} catch (err) {
		fs.remove(filename);
		return process.exit(0);
	}

	if (!page) page = webpage.create();

	page.viewportSize = {
		width: line.width || 1280,
		height: line.height || 960
	};

	page.paperSize = {
		format: line.paperFormat || 'A4',
		orientation: line.orientation || 'portrait',
		margin: line.margin || '0cm'
	};

	if (line.crop) page.clipRect = page.viewportSize;

	page.open(line.url, function(st) {
		if (st !== 'success') {
			fs.write(filename, '!', 'w');
			page = null;
			loop();
			return;
		}

		var render = function() {
			setTimeout(function() {
				if (line.printMedia) forcePrintMedia();
				page.render(filename, {format:line.format || 'png'});
				page = null;
				loop();
			}, 0);
		};

		var waitAndRender = function() {
			var timeout = setTimeout(function() {
				page.onAlert('webpage-renderable');
			}, 10000);

			var rendered = false;
			page.onAlert = function(msg) {
				if (rendered || msg !== 'webpage-renderable') return; 
				rendered = true;
				clearTimeout(timeout);
				render();
			};

			page.evaluate(function() {
				if (window.renderable) return alert('webpage-renderable');
				var renderable = false;
				Object.defineProperty(window, 'renderable', {
					get: function() {
						return renderable;
					},
					set: function(val) {
						renderable = val;
						alert('webpage-renderable');
					}
				});
			});
		};

		var renderable = page.evaluate(function() {
			return window.renderable;
		});
		if (renderable === false) return waitAndRender();
		render();

	});
};
Example #25
0
module.exports = function(data, done, worker) {

    var page = webpage.create();
    page.clearCookies();
    page.clearMemoryCache();
    page.settings.resourceTimeout = 30000;

    var resources = [];
    var startTime = -1;
    var endTime = -1;

    var address = 'http://' + data.url;

    // PhantomJS own onLoadFinished event does not work always so we basically have to implement it on our own
    // For this we check the requests and as soon as for some time there are no outgoing requests (and all responses
    // have arrived) we assume the page is loaded

    // if after 100ms no other request is made we think the page is loaded
    var FINAL_TIMEOUT = 100;

    var finalCheckTimeout = null;
    var openRequests = 0;

    var isLoaded = false;
    function pageLoaded(status) {
        if (!isLoaded) {
            isLoaded = true;
            if (status !== 'success') {
                done(new Error('Crawl Error: ' + page.reason + ' for ' + page.reason_url));
            } else {
                logPage();
            }
        }
    }

    function logPage() {
        var endTime = new Date();
        var title = page.evaluate(function () {
            return document.title;
        });

        var har = createHar(address, title, startTime, endTime, resources);

        // we dont want to have 1m files in one directory, we would prefer to have 1m files divided into 1000 directories
        var dirId = parseInt(data.id / 1000)*1000;
        var fileName = __workerDirname + '/results/' + dirId + '/' + data.id + '-' + data.url.replace(/[^\w.,;+\-]/g, '_') + '.json';
        fs.write(fileName, JSON.stringify(har, null, 4), 'w');

        done();
    }




    page.onLoadStarted = function () {
        startTime = new Date();
    };

    page.onResourceRequested = function (req) {
        clearTimeout(finalCheckTimeout);
        resources[req.id] = {
            request: req,
            startReply: null,
            endReply: null
        };
        openRequests++;
    };

    page.onResourceReceived = function (res) {
        if (res.stage === 'start') {
            resources[res.id].startReply = res;
        } else if (res.stage === 'end') {
            resources[res.id].endReply = res;
            openRequests--;

            if (openRequests === 0) {
                finalCheckTimeout = setTimeout(function() {
                    if (!isLoaded) {
                        console.log('ALTERNATIVE LOADING EVENT!')
                    }
                    pageLoaded('success'); // we assume everything is fine
                }, FINAL_TIMEOUT);
            }
        }
    };

    page.onResourceError = function (resourceError) {
        page.reason = resourceError.errorString;
        page.reason_url = resourceError.url;
    };

    page.onError = function (msg, trace) {
        // we actually just ignore errors happening on the page itself
    };

    page.open(address, pageLoaded);

};
Example #26
0
(function() {
    var pageModule = require('webpage');
    t.assertEquals(utils.isWebPage(pageModule), false, 'isWebPage() checks for a WebPage instance');
    t.assertEquals(utils.isWebPage(pageModule.create()), true, 'isWebPage() checks for a WebPage instance');
    t.assertEquals(utils.isWebPage(null), false, 'isWebPage() checks for a WebPage instance');
})();
Example #27
0
/**
 * @constructor
 */
function Bot (data) {
  /** @private This object */
  var self = this
    /**
     * Action to execute (i.e add or edit)
     *@private
     */
  self._action = data.action
    /**
     * Salesforce login
     * @private
     */
  self._login = data.login
    /**
     * Salesforce passord
     * @private
     */
  self._password = data.password
    /**
     * boolean indicating whether node is standard or not
     *@private
     */
  self._standard = data.standard // (data.standard == 'true') ? true : false
    /**
     * Node integration value
     * @private
     */
  self._integrationValue = data.integrationValue
    /**
     * Node iso code
     * @private
     */
  self._isoCode = data.isoCode
    /**
     * Node label
     * @private
     */
  self._label = data.text
    /**
     * Indicates whether node is active or not
     * @private
     */
  self._active = data.active // (data.active == 'true') ? true : false
    /**
     * Indicates whether node is visible or not
     * @private
     */
  self._visible = data.visible // (data.visible == 'true') ? true : false
    /**
     * Node parent iso code. Undefined when node is a country
     * Equal to coutry iso code when node is a state
     * @private
     */
  self._countryIsoCode = (data.typeNode === TYPE_NODE.COUNTRY) ? data.isoCode : data.parentIsoCode
    /**
     * Type of node (i.e state or country)
     * @private
     */
  self._typeNode = data.typeNode
    /**
     * Indicates whether trace option has been selected or not
     * @private
     */
  self._trace = data.trace // (data.trace == 'true') ? true : false
    /**
     * Salesforce login url (i.e https://test.salesforce.com or https://login.salesforce.com')
     * @private
     */
  self._loginUrl = data.loginUrl
    /**
     * Indicates whether check only option has been selected or not
     * @private
     */
  self._checkOnly = data.checkOnly // (data.checkOnly == 'true') ? true : false
    /**
     * Log directory's path
     * @private
     */
  self._path = data.debugFolderPath
    /**
     * Instance of phantomjs WebPage module
     * @private
     */
  self._page = WebPage.create()
    /** @private */
  self._countryFound = false
    /** @private */
  self._stateFound = false
    /** @private */
  self._countryLinkMap = {}
    /** @private */
  self._stateLinkMap = {}

  self._entitled = '[' + self._action + ' ' + self._typeNode + ' ' + self._label + '] '

  self._steps = [function () {
    self._page.open(self._loginUrl)
    return {
      message: self._entitled + 'Navigate to:' + self._loginUrl,
      done: true
    }
  },
  self.credentialHandler(),
  self.clickEltByIdHandler('Login'),
  function () {
    var found = self.waitForId('setupLink')
    var message = self._entitled + 'Waiting for logged in'
    if (found) {
      message = self._entitled + 'Logged in'
    }
    return {
      message: message,
      done: found
    }
  },
  function () {
    var url = self._page.url.replace('/home/home.jsp', '/i18n/ConfigStateCountry.apexp?setupid=AddressCleanerOverview')
    self._page.open(url)
    return {
      message: self._entitled + 'Navigate to: countries and states page',
      done: true
    }
  }]
}
Example #28
0
phantom.createPage = function () {
	var page  = webpage.create();
	var id = setup_page(page);
	return { pageId: id };
};
// Code to be run by PhantomJS.
// The docs for these modules are here: http://phantomjs.org/api/
// Note that the 'fs' module here has a different API than the one in node.js core.
var webpage = require('webpage');
var system = require('system');

var page = webpage.create();

var forcePrintMedia = function() {
  page.evaluate(function() {
    var findPrintMedia = function() {
      var styles = [];

      Array.prototype.slice.call(document.querySelectorAll('style')).forEach(function(el) {
        styles.push(el.innerText);
      });
      Array.prototype.slice.call(document.querySelectorAll('link')).forEach(function(el) {
        if (el.rel && el.rel.indexOf('stylesheet') === -1) return;

        try {
          // try-catch is just precaution (we already set web-security to no)

          var xhr = new XMLHttpRequest();

          // 99.99% of the cases we just hit the cache so no real io
          xhr.open('GET', el.href, false);
          xhr.send(null);

          styles.push(xhr.responseText);
        } catch (err) {
          // do nothing
Example #30
0
function go_page(result, url, ua, cb) {
	var page = webpage.create();

	page.settings.userAgent = ua;
	page.settings.resourceTimeout = RES_TIMEOUT;

	page.onError = function() {};

	page.onResourceReceived = function(response) {
		if (response.url in used)
			return;
		used[response.url] = true;


		var last, now, exp;
		var etag = '';

		var ret = response.headers.every(function(header) {

			switch(header.name.toLowerCase()) {
			case 'date':
				now = +new Date(header.value);
				break;
			case 'expires':
				exp = +new Date(header.value);
				break;
			case 'last-modified':
				last = +new Date(header.value);
				break;
			case 'content-type':
				if ( !(header.value.toLowerCase() in MIME) )
					return false;
				break;
			case 'etag':
				etag = header.value;
				break;
			}
			return true;
		});

		if (!ret) return;
		if (!exp || !last) return;
		if (!now) now = Date.now();

		var dayStable = ms2day(now - last);
		var dayCached = ms2day(exp - now);

		//
		// 放弃缓存时间短或者经常修改的资源
		//
		if (dayStable < MIN_STABLE_DAY || dayCached < MIN_CACHE_DAY) {
			return;
		}

		result.push({
			url: response.url,
			cache: dayCached,
			stable: dayStable,
			etag: etag
		});
	};

	page.open(url, function() {
		clearTimeout(tid);
		done();
	});

	var tid = setTimeout(done, PAGE_TIMEOUT);

	function done() {
		cb();
		page.close();
	}
}