Skip to content

Commit

Permalink
Merge pull request #6 from hotrush/pr/5
Browse files Browse the repository at this point in the history
Images waiting and timeout
  • Loading branch information
hotrush authored Dec 27, 2017
2 parents d5773e5 + 05c7d20 commit 462c991
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 21 deletions.
11 changes: 5 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,20 @@ php:
- 5.5
- 5.6
- 7.0
- 7.1
- 7.2
- nightly
- hhvm

matrix:
allow_failures:
- php: 7.0
- php: nightly
- php: hhvm

before_install:
- wget http://security.ubuntu.com/ubuntu/pool/main/i/icu/libicu52_52.1-3ubuntu0.4_amd64.deb
- sudo dpkg -i libicu52_52.1-3ubuntu0.4_amd64.deb
- wget http://security.ubuntu.com/ubuntu/pool/main/i/icu/libicu52_52.1-3ubuntu0.7_amd64.deb
- sudo dpkg -i libicu52_52.1-3ubuntu0.7_amd64.deb

before_script:
- composer self-update
- composer install --prefer-source --no-interaction --dev

script: phpunit
script: vendor/bin/phpunit
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Take website's screenshots with PHP/PhantomJS and save them to PNG, JPG or PDF.
Also you can take a look at simple microservice with lumen and this package - [hotrush/Webshotter-microservice](https://github.com/hotrush/Webshotter-microservice).

## Changelog
***0.1.6*** - added ```waitForImages()``` and ```imagesLoadingTimeout```

***0.1.5*** - custom ```$templatePath``` fixed, thanks to [mizansyed](https://github.com/mizansyed)

***0.1.3*** - added ```timeout``` property that allow to limit page load timeout (using [onResourceTimeout](http://phantomjs.org/api/webpage/handler/on-resource-timeout.html) phantomjs feature). If timeout reached ```TimeoutException``` will be thrown.
Expand Down Expand Up @@ -42,6 +44,8 @@ $jpg = $webshot
->setHeight(800)
->setTimeout(5) // set timeout in seconds, 30 seconds default
->setFullPage(true) // set to true to get full page screenshot (width/height will be used for viewport only)
->waitForImages() // wait when all images will load
->setImagesLoadingTimeout() // images loading timeout, will failt if not loaded
->saveToPng('github', $path);
```

Expand Down
43 changes: 43 additions & 0 deletions src/hotrush/Webshotter/Webshot.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ class Webshot
*/
private $timeout;

/**
* Wait while all page images will be loaded
*
* @var bool
*/
private $waitForImages;

/**
* Images waiting timeout
*
* @var int
*/
private $imagesLoadingTimeout;

/**
* Webshot constructor.
*
Expand All @@ -78,6 +92,8 @@ public function __construct($binPath = null, $templatePath = null)
}
$this->fullPage = false;
$this->timeout = 30;
$this->waitForImages = false;
$this->imagesLoadingTimeout = 30;

return $this;
}
Expand Down Expand Up @@ -166,6 +182,31 @@ public function setTimeout($timeout)
return $this;
}

/**
* Let webshotter wait while images will load
*
* @return $this
*/
public function waitForImages()
{
$this->waitForImages = true;

return $this;
}

/**
* Set images loading timeout
*
* @param $timeout
* @return $this
*/
public function setImagesLoadingTimeout($timeout)
{
$this->imagesLoadingTimeout = (int) $timeout;

return $this;
}

/**
* Render PhantomJS script template
*
Expand All @@ -180,6 +221,8 @@ private function renderTemplate($filePath)
'height' => $this->height,
'fullPage' => $this->fullPage,
'timeout' => $this->timeout * 1000, // convert into milliseconds
'waitForImages' => $this->waitForImages,
'imagesLoadingTimeout' => $this->imagesLoadingTimeout * 1000, // convert into milliseconds
), $filePath);
}

Expand Down
53 changes: 47 additions & 6 deletions src/views/webshotter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,58 @@
page.settings.resourceTimeout = <?php echo $timeout; ?>;

page.open('<?php echo $url; ?>', function () {
<?php if ($waitForImages) { ?>
waitFor(function() {
return page.evaluate(function() {
for(var i = 0; i < document.images.length; i++) {
if (!document.images[i].complete) {
return false;
}
}
return true;
});
}, function() {
savePage();
phantom.exit();
}, <?php echo $imagesLoadingTimeout; ?>);
<?php } else { ?>
savePage();
phantom.exit();
<?php } ?>
});

function savePage() {
page.viewportSize = {
width: <?php echo $width; ?>,
height: <?php echo $height; ?>
};
<?php if (!$fullPage) { ?>
page.clipRect = {
width: <?php echo $width; ?>,
height: <?php echo $height; ?>
}
page.clipRect = {
width: <?php echo $width; ?>,
height: <?php echo $height; ?>
}
<?php } ?>
page.render('<?php echo $path; ?>');
phantom.exit();
});
}

<?php if ($waitForImages) { ?>
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000,
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if (!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
clearInterval(interval); //< Stop this interval
}
}
}, 250);
};<?php } ?>
31 changes: 31 additions & 0 deletions tests/PropertiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ public function testTimeoutProperty()
$this->assertEquals(10, PHPUnit_Framework_Assert::readAttribute($webshot, 'timeout'));
}

public function testImagesWaitProperty()
{
$webshot = new Webshot();
$this->assertEquals(false, PHPUnit_Framework_Assert::readAttribute($webshot, 'waitForImages'));
$webshot->waitForImages();
$this->assertEquals(true, PHPUnit_Framework_Assert::readAttribute($webshot, 'waitForImages'));
}

public function testImagesTimeoutProperty()
{
$webshot = new Webshot();
$this->assertEquals(30, PHPUnit_Framework_Assert::readAttribute($webshot, 'imagesLoadingTimeout'));
$webshot->setImagesLoadingTimeout(10);
$this->assertEquals(10, PHPUnit_Framework_Assert::readAttribute($webshot, 'imagesLoadingTimeout'));
}

public function testTemplateRendering()
{
$webshot = new Webshot();
Expand All @@ -77,6 +93,21 @@ public function testTemplateRendering()
$this->assertEquals($mock, $method->invokeArgs($webshot, array('tests/tmp/github.png')));
}

public function testTemplateRenderingWithImagesWait()
{
$webshot = new Webshot();
$webshot
->setUrl('https://github.com')
->setWidth(1200)
->setHeight(800)
->waitForImages();
$mock = file_get_contents(realpath(dirname(__FILE__).'/../tests/data/template_images.php'));
$reflection = new ReflectionClass('hotrush\Webshotter\Webshot');
$method = $reflection->getMethod('renderTemplate');
$method->setAccessible(true);
$this->assertEquals($mock, $method->invokeArgs($webshot, array('tests/tmp/github.png')));
}

public function testTemplateProperty()
{
$path = realpath(dirname(__FILE__));
Expand Down
14 changes: 14 additions & 0 deletions tests/TimeoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,18 @@ public function testTimeout()
->setTimeout(5)
->saveToPng('delay', $path);
}

public function testImagesTimeout()
{
$path = realpath(dirname(__FILE__).'/../tests/tmp/');
$webshot = new Webshot();
$webshot
->setUrl('https://github.com')
->setWidth(1200)
->setHeight(800)
->setTimeout(5)
->waitForImages()
->setImagesLoadingTimeout(10)
->saveToPng('imagestimeout', $path);
}
}
14 changes: 9 additions & 5 deletions tests/data/template.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@
page.settings.resourceTimeout = 30000;

page.open('https://github.com', function () {
savePage();
phantom.exit();
});

function savePage() {
page.viewportSize = {
width: 1200,
height: 800 };
page.clipRect = {
width: 1200,
height: 800 }
page.clipRect = {
width: 1200,
height: 800 }
page.render('tests/tmp/github.png');
phantom.exit();
});
}

53 changes: 53 additions & 0 deletions tests/data/template_images.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
var page = new WebPage();
page.settings.javascriptEnabled = true;
page.onResourceTimeout = function(request) {
phantom.exit();
};
page.settings.resourceTimeout = 30000;

page.open('https://github.com', function () {
waitFor(function() {
return page.evaluate(function() {
for(var i = 0; i < document.images.length; i++) {
if (!document.images[i].complete) {
return false;
}
}
return true;
});
}, function() {
savePage();
phantom.exit();
}, 30000);
});

function savePage() {
page.viewportSize = {
width: 1200,
height: 800 };
page.clipRect = {
width: 1200,
height: 800 }
page.render('tests/tmp/github.png');
}

function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000,
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if (!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
clearInterval(interval); //< Stop this interval
}
}
}, 250);
};
8 changes: 4 additions & 4 deletions tests/template/webshotter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
height: <?php echo $height; ?>
};
<?php if (!$fullPage) { ?>
page.clipRect = {
width: <?php echo $width; ?>,
height: <?php echo $height; ?>
}
page.clipRect = {
width: <?php echo $width; ?>,
height: <?php echo $height; ?>
}
<?php } ?>
page.render('<?php echo $path; ?>');
phantom.exit();
Expand Down

0 comments on commit 462c991

Please sign in to comment.