Issue generating a pdf with phantomjs when there is flexbox - phantomjs

Does anyone know if generating a pdf with phantomjs works when a webpage uses flexbox ?
I'm using the example here to generate a pdf and it works very nicely except for the components that use flexbox
https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js?utm_content=bufferda3e0&utm_source=buffer&utm_medium=twitter&utm_campaign=Buffer
I've also tried to generate a pdf out of www.stackoverflow.com (which uses flexbox for some divs) and I get the same issue, pretty much the element with flexbox takes 100% of the width and prevents showing other divs in the same "row".

PhantomJS is very much outdated, can you migrate to puppeteer? (is a node.js module with Chromium underneath)
https://github.com/GoogleChrome/puppeteer/blob/master/examples/pdf.js
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
// page.pdf() is currently supported only in headless mode.
// #see https://bugs.chromium.org/p/chromium/issues/detail?id=753118
await page.pdf({
path: 'hn.pdf',
format: 'letter'
});
await browser.close();
})();

Related

How to enter Immersive Reader on Microsoft Edge through Selenium?

On a high level, does anyone know how to enter the Immersive Reader mode on Microsoft Edge when it is available for a given webpage through Selenium?
My aim is to load up a page, enter Immersive Reader, and save the page's source code to disk. I'm firing up Edge through Docker and I'm pragmatically connecting to it via a Node.js script.
I've tried driver.actions().sendKeys(KEY.F9), but that doesn't work since I'm targeting the browser and not a DOM element.
Many thanks for all your help.
New
Just run
driver.get('read://' + url)
and the site is loaded in immersive reader mode if available.
Old
To interact with the UI you have to use pyautogui (pip install pyautogui) and then run this code while the browser window is on focus/active:
import pyautogui
pyautogui.press('F9')
It is also useful for example to save a pdf by interacting with the popup window appearing when pressing CTRL+S.
Here's a bit of code for anyone else who might stumble across this:
Credits to #sound wave for helping me get there!
const { Builder } = require('selenium-webdriver');
const fs = require('fs');
(async () => {
const driver = await new Builder().forBrowser('MicrosoftEdge').usingServer('http://localhost:4444').build();
await driver.get('read://https://www.bbc.co.uk/news/entertainment-arts-64302120'); // this URL needs to be Immersive Reader supported
await driver.switchTo().frame(0);
const pagesource = await driver.getPageSource();
fs.writeFile('test.html', pagesource, err => {
if (err) {
console.log(err);
}
});
const title = (await driver.getTitle()).trim();
console.log(title);
await driver.quit();
})().catch((e) => console.error(e));

webdriverio - download pdfs in chrome

I am new to using webdriverio, and attempting to automatically download a pdf file. The file opens in the browser and I cannot figure out how to download it - ideally to a folder specified on my local machine. I see some old forum posts which possibly suggest using chromedriver, however, due to minimal code snippets provided, I cannot understand if it's the correct approach though. Here is what I have this far (although the last two lines do not work):
const LoginPage = require('../pageobjects/login.page');
describe('Payroll Download Application', () => {
it('Login Fail Page', async () => {
await LoginPage.open();
await LoginPage.login();
await $("a[href='PayCycleReports']").click()
await $('a=Payroll Summary').click()
const handles = await browser.getWindowHandles()
await browser.switchToWindow(handles[1])
const elem = await $("#viewer").shadow$("#toolbar").shadow$("#downloads").shadow$("#downloads").shadow$("#download")
await elem.click()
});
});
Any help to figure it out would be greatly appreciated. Thanks :)
This can be done with browser.execute.
It will be necessary to select the element through JS and add the 'download' attribute to it. If you click on an element with the 'download' attribute, the pdf will not open but will be downloaded.
Example:
await browser.execute(function(){
document
.querySelector("#node-32 > div > div > div > ul:nth-child(4) > li:nth-child(1) > a")
.setAttribute("download", "download")
},
);
If you need a different selector (not CSS) you can use getElementById , getElementsByName, getElementsByTagName, getElementsByClassName, getElementByXPathand others.

Puppeteer - Connecting to HTTPS website through a proxy with authentication doesn't work

I have been trying to solve this issue for the past 2 days and haven't been able to. I've looked this up everywhere and still no solution.. Here's the code:
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
const PROXY_SERVER_IP = 'IP.IP.IP.IP';
const PROXY_SERVER_PORT = '1234';
const PROXY_USERNAME = 'username';
const PROXY_PASSWORD = 'password';
(async () => {
const browser = await puppeteer.launch({
args: [`--proxy-server=http://${PROXY_SERVER_IP}:${PROXY_SERVER_PORT}`],
});
const page = await browser.newPage();
await page.authenticate({
username: PROXY_USERNAME,
password: PROXY_PASSWORD,
});
await page.goto('https://www.google.ca/', {
timeout: 0,
});
await page.screenshot({ path: 'test4.png', fullPage: true });
await browser.close();
})();
I get a navigation timeout error on the page.goto() call because it just hangs for some reason. I can't figure out why. When I put a proxy that doesn't require authentication, it works. I'm thinking of switching to another headless solution because of this one issue and I would really appreciate some help.
So I figured it out. Turns out the proxy was really bad for some reason. The reason why Axios and cURL gave fast responses was because they just get the initial HTML code and unlike headless browsers, don't actually do anything with HTML text. With headless browsers, they actually make all the requests for the assets as well (css, images, etc.) and any other network requests and it's all going through the proxy, so it's much slower. When I tried a different proxy (one that requires authentication), it was much faster.

TestCafe: Testing a Page Opening a PDF in a New Tab

Part of the web application I am testing is to click a button, which normally opens a PDF in a new tab. This enables the user to go forward in the application. The PDF can be ignored.
Currently, my strategy is to click the button and then navigate back using ClientFunction. TestCafe successfully opens the PDF when the button is clicked, but it is opened in the same tab and the test is then stuck. Navigating back changes the URL, but the PDF is still displayed.
const goBack = ClientFunction(() => window.history.back())
await this.t.click(this.button)
await this.t.wait(10000)
await goBack()
Is TestCafe currently able to bypass this issue, as I don't need to actually do anything with the PDF?
TestCafe allows testing html pages, but not PDF files. So, you can check the generated link to the PDF file as a string without actually following this link. For example:
const overrideWindowOpen = ClientFunction(() => {
window.open = function (url) {
window.__lastWindowOpenUrl = url;
};
});
const getResultUrl = ClientFunction(() => window.__lastWindowOpenUrl);
await overrideWindowOpen();
await t
.click(this.button)
.expect(getResultUrl()).eql('http://example.com/path/to/PDF/93023813-0984-1');
See also: Multiple Browser Windows

How do you test AngularJS cookies in an end-to-end test?

I have a simple service that sets cookies in angular, but there's no obvious way to test that they've been set in an end-to-end test.
The code to test is as simple as
var splashApp = angular.module('splashApp', ['ngCookies']);
splashApp.controller('FooterController', function ($location, $cookies) {
$cookies.some_cookie = $location.absUrl();
});
But I can't find any docs on how to test. Here's what I have found:
How to access cookies in AngularJS?
http://docs.angularjs.org/api/ngCookies.$cookies
http://docs.angularjs.org/api/ngCookies.$cookieStore
I've also tried
angular.scenario.dsl('cookies', function() {
var chain = {};
chain.get = function(name) {
return this.addFutureAction('get cookies', function($window, $document, done) {
var injector = $window.angular.element($window.document.body).inheritedData('$injector');
var cookies = injector.get('$cookies');
done(null, cookies);
});
};
return function() {
return chain;
}
});
But this returns only the cookies for the parent browser, not the page I want to test.
Any examples on how to do this?
It seems like you need to use PhantomJS.
PhantomJS is a headless WebKit scriptable with a JavaScript API. It
has fast and native support for various web standards: DOM handling,
CSS selector, JSON, Canvas, and SVG. --PhantomJS website
It has support for custom cookies in its API.
In terms of testing, this is probably your best choice.
You might also want to look at CasperJS to help test page navigation.