Where are playwright screenshots going - and how can I control this? - e2e-testing

I have a really basic playwright (v1.18.1) test on Windows (11):
import { test, expect } from '#playwright/test';
test('test', async ({ page }) => {
await page.goto('http://whatsmyuseragent.org/');
//await page.screenshot({ path: `./tests/tmp/screenshots/whats.my.ua.${project:name}.png` });
await page.screenshot();
});
And when I run this - it says it worked
Running : cd C:\playwright\tests && npx playwright test whats_my_user_agent.spec.ts --reporter=list
Running 5 tests using 3 workers
ok [webkit] › whats_my_user_agent.spec.ts:3:1 › test (3s)
ok [firefox] › whats_my_user_agent.spec.ts:3:1 › test (4s)
ok [chromium] › whats_my_user_agent.spec.ts:3:1 › test (5s)
ok [Mobile Chrome] › whats_my_user_agent.spec.ts:3:1 › test (2s)
ok [Mobile Safari] › whats_my_user_agent.spec.ts:3:1 › test (2s)
5 passed (8s)
but I can find no sign of the screenshot file - where are they [there is no feedback giving any hints]. Also - is there a way to control the saved filename (including the project name so that I don't save 5 png files over each other).

As I see it, if you uncomment the line in which you specify the path for your screenshot to be stored, you should find it there, for example, this:
import { test, expect } from '#playwright/test';
test('testing screenshot path', async ({ page }) => {
await page.goto('https://playwright.dev/');
await page.screenshot({ path:`./screenshots/screenshot.png` });
});
should result in you having a screenshot of the website named 'screenshot.png' in a folder named 'screenshots' in the root of your project. If there's no folder by that name, it will be created.
As for your question, since this would run the same step (saving a screenshot with a certain name in a certain path) for every project that you're running, your screenshot would be overwritten, leaving you only with the screenshot your last project run. If you'd like all screenshots to be stored, or screenshots for one project in particular (although running several projects), you can play with testInfo. Say you only want to store the screenshots for the project you're running in chromium, though checking the steps pass in every other project; you can do something like this:
test('testing chromium screenshots', async ({ page }, testInfo) => {
await page.goto('https://playwright.dev/');
if (testInfo.project.name === 'chromium') {
await page.screenshot({ path:`./screenshots/${testInfo.title}.png` });
}
});
This would store a screenshot named 'testing chromium screenshots' with the extension .png in the folder 'screenshots' in the root of your project, tested with chromium, while checking the test pass in every other project you might be running.
Hope all this helps.

Ok - I found out how - I needed to include workerInfo in the async declaration, and then I can reference it in the screenshot call:
import { test, expect } from '#playwright/test';
test('test', async ({ page }, workerInfo) => { <----------- added workerInfo
await page.goto('http://whatsmyuseragent.org/');
await page.screenshot({ path: "./tests/tmp/screenshots/whats.my.ua."+workerInfo.project.name+".png" });
// ^^ referenced it with this
});

The screenshot is always returned as a buffer by the screenshot function. If you don't pass a path the only way to get that screenshot is through the buffer.

Related

Firebase Firestore SDK will not run with Mocha+Chai unit tests

Issue:
When running a test in Mocha, we need to add a document to the local emulated Firestore. The local emulated setup is working but not within the Mocha test, specifically.
Node Version: 14.18.1, chai: 4.3.4, firebase-admin: 10.0.0, firebase: 9.1.3
Explaination
Working Locally:
If I were to try and run:
await conref.doc('testDoc').set({test: true}); before the first Mocha
describe(), I can verify the document is added to my local Firestore at
localhost:8080
const db = getFirestore();
const ref = db.collection('testCollection');
await ref.doc('testDoc').set({test: true});
const testDoc = await db.collection('testCollection').doc('testDoc').get();
console.log(testDoc.data());
prints { test: true }, confirming packages and connection is working
Breaking In Mocha:
..however placing similar logic inside my describe() causes the test to report as
errored each and every time, returning a red (1) instead of a green checkmark:
describe("example", async function() {
it("should write to Firestore in a mocha test", async function() {
const db = getFirestore();
const ref = db.collection('testCollection');
await ref.doc('testDoc').set({test: true}); // < causes error
};
};
screenshot
Imports
Firebase has had different version and its been confusing, so I will include the imports I am using for both of these examples below, in case this might be very wrong.
import { getFirestore } from 'firebase-admin/firestore';
import { initializeApp, applicationDefault } from 'firebase-admin/app';
initializeApp({
credential: applicationDefault(),
databaseURL: process.env.FIREBASE_DATABASAE_URL,
});
Attempts
Tried adjusting timeouts, thinking maybe the Mocha suite was not waiting for the doc to be added, but even an addition of this.timeout(10000); within the test did not change the outcome.
Tried setting the doc before the test, which worked, so I put this in a function and tried calling it from within the test as if I was praying on a Hail Mary, but to no surprise this had no effect.
Tried connecting to my production Firestore but still no cigar (via removing the FIRESTORE_EMULATOR_HOST env).
Added done() at the end of the test, but did not change outcome

Jest puppeteer typescript reference error Page not found

Trying to setup typescript jest with puppeteer
i following step by step instructions as mentioned below
Jest-puppeteer with typescript configuration
there is a simple test
describe('Google', () => {
beforeAll(async () => {
await page.goto('https://google.com')
})
it('should display "google" text on page', async () => {
await expect(page).toMatch('google')
})
})
when i run my test i get weird error
ReferenceError: page is not defined
and it is pointing to the 'await page' object inside beforeAll
i also notice chrome try to kick in and but does not launch may be this error is b/c chrome could not launch.
jest-puppeteer library is responsible for launching a browser and providing browser and page objects
and here is the code taken from the page mentioned above in link
//jest-puppeteer.config.js
let jest_puppeteer_conf = {
launch: {
timeout: 30000,
dumpio: true // Whether to pipe the browser process stdout and stderr
}
}
const isDebugMode = typeof v8debug === 'object' || /--debug|--inspect/.test(process.execArgv.join(' '));
if (isDebugMode) {
jest_puppeteer_conf.launch.headless = false; // for debug: to see what the browser is displaying
jest_puppeteer_conf.launch.slowMo = 250; // slow down by 250ms for each step
jest_puppeteer_conf.launch.devtools = true; // This lets you debug code in the application code browser
jest_puppeteer_conf.launch.args = [ '--start-maximized' ]; // maximise the screen
}
module.exports = jest_puppeteer_conf;
there is a small debug section at the bottom which reminds to add following types i already have them and still no luck, any help is appreciated.
"compilerOptions": {
.....
"types": [
.......
"puppeteer",
"jest-environment-puppeteer",
"expect-puppeteer"
]
}
commenting out the following line fix the issue.
// testEnvironment: "node"

nrwl-Nx and Cypress, verification timing out with failed --smoke-test in Windows 7

I'm trying to follow along with this tutorial on the NX website. The 2nd part has us setting up e2e testing with Cypress. I followed everything as said and even went as far as commenting out my code and pasting theirs into my files. I'm not getting any errors in the console. The error I see in Node says
Cypress verification timed out
This command failed with the following output:
C:.....\Cache\3.3.1\Cypress\Cypress.exe --smoke-test --ping=852
The tutorial also says there's a UI that should pop up on our app, which I don't see anything of the sort.
After generating the workspace and the application it has us modify the app.po.ts file by adding a couple constants, so far mine looks like this
export const getGreeting = () => cy.get('h1');
export const getTodos = () => cy.get('li.todo');
export const getAddTodoButton = () => cy.get('button#add-todo');
next it tells us to update the app.spec.ts file of the e2e test by adding this
import { getAddTodoButton, getTodos } from '../support/app.po';
describe('TodoApps', () => {
beforeEach(() => cy.visit('/'));
it('should display todos', () => {
getTodos().should(t => expect(t.length).equal(2));
getAddTodoButton().click();
getTodos().should(t => expect(t.length).equal(3));
});
});
The version of this file generated by Nx comes with this already in it
import { getGreeting } from '../support/app.po';
describe('todos', () => {
beforeEach(() => cy.visit('/'));
it('should display welcome message', () => {
getGreeting().contains('Welcome to todos!');
});
});
I originally tried adding the extra test underneath it and added the new imports. After getting the error message I thought maybe I needed to combine the tests into one test which looks like this.
describe('TodoApps', () => {
beforeEach(() => cy.visit('/'));
it('should display welcome message', () => {
getGreeting().contains('Welcome to todos!');
});
it('should display todos', () => {
getTodos().should(t => expect(t.length).equal(2));
getAddTodoButton().click();
getTodos().should(t => expect(t.length).equal(3));
});
});
I'm still getting the same error in Node and have no clue as to what I'm doing wrong. Prior to starting the project I updated node, npm and angular cli. I downloaded Angular Console for VS Code but am running into problems with it so I've just been using the Node Terminal and Brackets. Can anyone help?
if you in windows then you can solve this verification timeout issue by navigating to:
'C:\Users\<user>\AppData\Local\Cypress\Cache\3.4.0\Cypress'
then just double click on Cypress.exe.
After this close it and go back to your ide or terminal and redo what threw the error

output the cypress browser log messages when running headless in CI

I am using cypress-io and cypress-axe to run browser tests and check if a page has accessibility violations.
I have this task:
function reportA11yViolations(violations: Result[]) {
const errors: string[] = [];
violations.forEach((v: Result) => v.nodes.forEach((node: NodeResult) => {
errors.push(node.failureSummary);
}));
cy.log(errors.join("\n"));
}
Cypress.Commands.add("checkA11yAndReportViolations", (context, options) => {
cy.checkA11y(context, options, reportA11yViolations);
});
I can see all the browser log messages when running through the nice browser app.
But what about when I am running in headless in the ci environment?
Is there anyway I can display these errors anywhere or write them to a file?
You can output the cypress logs to a file
cy.writeFile('accessibilityReport.txt', `${node.failureSummary} \n`, { flag: 'a+' });
a+ will append the result to the file. The build artifacts of the jenkins pipeline should have the report thus created.

Different browser behavior when pass .env variables in command for run tests

It's not actually a problem, but I do not fully understand, what happened and why.
I have this runner for my test. I test a React app.
let testcafe = null
const isCiEnv = process.env.CI === 'true'
const exit = async err => {
console.log('Exiting...')
if (testcafe) {
console.log('Closing TestCafe...')
testcafe.close()
}
console.log('Exiting process...')
process.exit(err ? 1 : 0)
}
console.log('Is CI ENV: ', isCiEnv)
console.log('Creating TestCafe...')
createTestCafe('localhost', 1337, 1338)
.then(tc => {
testcafe = tc
})
.then(() => {
console.log('Starting server...')
return startServer()
})
.then(() => {
console.log('Starting client...')
return startClient()
})
.then(() => {
console.log('Creating TestCafe Runner...')
return testcafe.createRunner()
})
.then(runner => {
console.log('About to start TestCafe Runner...')
return runner
.src([
'test/e2e/fixtures/auth.js'
])
.browsers({
path: isCiEnv
? '/usr/bin/chromium-browser'
: 'Chrome',
cmd: isCiEnv
? '--no-sandbox --disable-gpu'
: undefined
})
.screenshots('screenshots', true)
.run({
skipJsErrors: true,
selectorTimeout: 25000,
assertionTimeout: 25000
})
})
.then(failedCount => {
console.log('failed count:', failedCount)
return exit(failedCount)
})
.catch(err => {
console.error('ERR', err)
return exit(err)
})
In package.json i have this command for run test
"test:e2e": "HOST=0.0.0.0 NODE_ENV=test NODE_PATH=server babel-node test/e2e/index.js --presets stage-2"
But in the local environment, I run a test with this command
sudo REDIS_HOST=127.0.0.1 PORT=80 yarn test:e2e
That because on my local machine I have different config and I don't want to change it for everyone else.
Usually, test runs in a different, clear version of the browser, without any account data, plugins and etc. But in this case, tests run in a new browser window, but with all plugins and my account name. But, it's doesn't have cookie and session auth data from the browser window, in which I usually work (because I authorized on-site in the working browser and doesn't auth in test browser).
And if I change "Chrome" to "chrome" it stops run completely. Same behavior for Firefox and Safari.
Earlier, without passing REDIS_HOST and HOST, it works as usual and runs in a clean new browser window.
It's not a big problem, for now at least, but it's unexpected behavior and I don't understand, why it works this way.
I'm not very familiar with Node and React, and maybe this related to them.
Spec: macOS 10.12.5, Testcafe 0.20.3, Chrome 67
Specifying browsers using { path, cmd } is a legacy low-level option, you shouldn't use it. When a browser is specified in this way, TestCafe doesn't try to guess browser's type (Chrome, Firefox) and doesn't perform advanced initialization steps like creating a clean profile (because profile structure depends on browser's type). So it's better to use the following runner code:
.browsers(isCiEnv ? 'chromium --no-sandbox --disable-gpu' : 'chrome')

Resources