attaching screenshot to allure report using playwright - allure

How might I be able to attach screenshot to allure report using MS Playwright
test('basic test', async ({ page }) => {
await page.goto('https://playwright.dev/');
const screen1 = await page.screenshot({path: './screenshots/screenshot.png',fullPage: true});
allure.screenshot('screenShot', screen1, 'image/png');
const title = await page.locator('.navbar__inner .navbar__title');
await expect(title).toHaveText('Playwright');
//await title.screenshot({path: './screenshots/title.png'});
await page.close();
});
I already have allure installed using npm i -D allure-playwright
Yet I cannot get ad hoc screenshots attached to the rendered allure report during the test step.

Related

Browser not Defined error in Jest-Image-Snapshot Testing in React

I want to implement https://github.com/americanexpress/jest-image-snapshot#-api in my React application and tried writing one of the test cases but gives me an error saying the browser is not defined when trying to run a test using the command "npm test".I am using a library called Jest-Image-snapshot by americanexpress
import { toMatchImageSnapshot } from 'jest-image-snapshot';
expect.extend({ toMatchImageSnapshot });
jest.setTimeout(10000);
it('renders correctly', async () => {
const page = await browser.newPage();
await page.goto('https://localhost:3000');
const image = await page.screenshot();
expect(image).toMatchImageSnapshot();
});

Why can't react testing library access elements with Selenium?

I have a selenium / jest project. I have installed react testing library and a few packages, but when I try to make valid assertions, I get an error. Code:
import { Vocal } from '../../Models/vocalModel';
import {screen} from '#testing-library/dom';
const vocal = new Vocal()
// Test Variables here
let validEmail = 'email#email.com'
let validPassword = 'password'
let invalidEmail = 'ThisEmailIsNotValid'
let invalidPassword = 'ThisPassWordIsNotValid'
describe("Login Test Suite", () => {
beforeAll(async ()=>{
await vocal.navigate();
});
afterAll( async ()=>{
await vocal.quit();
});
test('A user can login and logout', async () =>{
await vocal.userLogin(validEmail, validPassword);
await vocal.userLogout();
let getSignUpButtonText = await vocal.getText(vocal.signUpButtonLogin)
console.log(getSignUpButtonText)
expect(screen.getByText("Sign Up")).toBeVisible();
})
});
When I run this test, the browser runs and the test fails at the final assertion. I get the following error: "TestingLibraryElementError: Unable to find an element with the text: Sign Up. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.".
See photo:
Image of Error here
I've consoled 'getSignUpButtonText' which is defined as the text of that button on the page and it returns "Sign Up" so I know that text is on the page. Why can't screen.getByText('Sign Up') find it?
I have tried a few different packages but I cant seem to get away from this error.

How should I be using playwright's toHaveScreenshot() within a cucumber test in a React Typescript project?

I'm wanting to implement visual regression testing into a ReactJS app. I already have playwright setup called through cucumber for some other BDD UI tests and wanted to make use of the built in toHaveScreenShot method for visual regression. However, whenever I run the test it throws this error:
Error: toHaveScreenshot() must be called during the test
Here's the test script definition:
package.json excerpt
"test:e2e": "cucumber-js --require cucumber.conf.js --require features/step_definitions/**/*.js --format #cucumber/pretty-formatter",
Here's an example of the code:
cucumber.conf.js
const {
Before,
BeforeAll,
AfterAll,
After,
setDefaultTimeout,
} = require("#cucumber/cucumber");
const { chromium } = require("playwright");
// in milliseconds
setDefaultTimeout(60000);
// launch the browser
BeforeAll(async function () {
global.browser = await chromium.launch({
headless: false,
slowMo: 1000,
});
});
// close the browser
AfterAll(async function () {
await global.browser.close();
});
// Create a new browser context and page per scenario
Before(async function () {
global.context = await global.browser.newContext();
global.page = await global.context.newPage();
});
// Cleanup after each scenario
After(async function () {
await global.page.close();
await global.context.close();
});
homepage.feature
Feature: Homepage
A simple homepage
Scenario: Someone visiting the homepage
Given a new visitor to the site
When they load the homepage
Then they see the page
homepage.js
const { Given, When, Then } = require("#cucumber/cucumber");
const { expect } = require("#playwright/test");
Given("a new visitor to the site", function () {});
When("they load the homepage", async () => {
await page.goto("http://localhost:3000/");
});
Then("they see the page", async () => {
const locator = page.locator('img[alt="An image you expect to see"]');
await expect(locator).toBeVisible();
await expect(locator).toHaveScreenshot();
});
I think the error is complaining that I'm not writing my tests in the usual test() method, but I've not come across anything similar in searches and don't know how to give this context, assuming that is the problem, while using Cucumber.
Can anyone suggest a solution? I'm at a bit of a loss.

How to check if alert has been called in Jest testing React using Typescript?

I have a HTML select with some options which when I press a button get submitted to a server. Depending on the response an alert is shown.
The method looks like this:
const sendOrder = async (json : string) => {
const request = await fetchUrl("<irrelevant url>", "POST", json);
if(request.status === 200){
const order = await request.json();
alert(`Created Order #${order.data.id}`)
}else{
alert("Order failed")
}
}
Now I have mocked the server using msw and my test looks something like this:
it('should create an order', async () => {
render(<ArticleList />);
render(<ShoppingCart afterSubmit={()=> {}}/>)
const articlesList = getNullSafeElement('articles');
await waitFor(() => {
expect(articlesList.children.length).toBe(2);
})
const orderButton = getNullSafeElement('submitBtn');
const shoppingCart = document.querySelector('#cart') as HTMLSelectElement;
const addressInput = document.querySelector('#address') as HTMLInputElement;
addressInput.value = "testAddress"
expect(shoppingCart.options.length).toBe(0);
fireEvent.click(articlesList.children[0]);
expect(shoppingCart.children.length).toBe(1);
fireEvent.click(orderButton);
});
I know for sure that this test runs as expected and that the request is definetly beeing sent to the mocked server by fireEvent.click(orderButton).
However, if I now want to do something like this expect(global.alert).toHaveBeenCalledTimes(1), it does not work.
Now I know that I have to mock the call and I saw some posts on SO about this issue
Mock or asser whether window.alert has fired
Test alert in React Native
But neither global.alert = jest.fn(), nor jest.spyOn(global, 'alert') have worked out. Both result in 0 calls.
So my question is: How can I test if alert() has been called in my test?
(I am creating a frontend using create-react-app with the typescript template and testing with Jest)

Why does Create React App .env for api keys doesn't work when uploaded to AWS Amplify

I added a dotenv file for an api key in my react app, i followed this tutorial: https://www.pluralsight.com/guides/hiding-secret-keys-in-create-react-app as well as this: https://create-react-app.dev/docs/adding-custom-environment-variables/ I prefixed it as REACT_APP_API_KEY. The app works locally but not when uploaded to AWS.
This the on load fetch:
useEffect(() => {
const fetchData = async () => {
try {
const url = `https://api.themoviedb.org/3/search/movie/?api_key=${process.env.REACT_APP_API_KEY}&language=en-US&query=all`;
const response = await fetch(url);
const data = await response.json();
setMovieList(data.results);
} catch (err) {
console.log(err);
}
};
fetchData();
}, []);
This the search submit button handler:
const handleSearch = useCallback(async () => {
try {
const url = `https://api.themoviedb.org/3/search/movie/?api_key=${process.env.REACT_APP_API_KEY}&language=en-US&query=${query}&page=1&include_adult=false`;
const response = await fetch(url);
const jsondata = await response.json();
await setMovies(jsondata.results);
} catch (err) {
console.log(err);
}
}, [query]);
Here's the local working app:
Here's the App uploaded in AWS
Typically, whenever you deploy a React app created with Create React App (CRA), you run yarn build and then upload the build directory to some hosting solution. There is no actual process binary that you run (from React's perspective) after that.
During development, CRA's toolchain (Webpack dev server) is a running process and handles the actual serving and building of content which means it has access to the variables from .env. Once you have run yarn build, CRA is hands off and all the execution is handled by some other server that CRA is oblivious to. Any variables that did exist are hard-injected into the built app at build time Referencing Environment Variables in the HTML.
If you need these variables to change based on a deployment, you should have another .env file that gets used in your build tools or make them regular environment variables available in your build script. Just about every continuous deployment (CI) tool has this capability.

Resources