I have created this issue on github: https://github.com/microsoft/playwright/issues/18580 since almost a year ago. I wonder if some here have face the same issue and if so how do they authenticate a real user during their test with playwright. I am using chrome.
This thread is trying to answer question "How to authenticate a real user during testing with Playwright?"
I posted my solution in two comments as jenvareto
on this GitHub issue: https://github.com/microsoft/playwright/issues/11164#issuecomment-1633293473
It's worked perfectly for me. If you use service credentials instead of passwords (like the Cypress plugin) the overall design will still apply but you'll either need to use the firebase-admin package or the Firebase Admin REST API (documentation: https://firebase.google.com/docs/reference/rest/auth).
I specifically wanted to ditch using the service credentials in automation and scripts so I have, but I have used it in the past. Let me know if you run into trouble with either method.
Hello @jennifer0419 , Thanks for the link. I tried but I am still unable to make it work. Here is my code
export function setAuthInBrowser() {
const valueRetrievedManuallyFromIndexDB = {
uid: 'xxxxx',
email: '[email protected]',
emailVerified: true,
displayName: 'xxx',
//...
};
function insertUser(db: IDBDatabase, user) {
const txn = db.transaction('firebaseLocalStorage', 'readwrite');
const store = txn.objectStore('firebaseLocalStorage');
const query = store.add({
value: valueRetrievedManuallyFromIndexDB,
fbase_key: `firebase:authUser:apiKey:[DEFAULT]`,
});
query.onsuccess = function (event) {
console.log(event);
};
query.onerror = function (event) {
console.log((event.target as any).errorCode);
};
txn.oncomplete = function () {
db.close();
};
}
const request = window.indexedDB.open('firebaseLocalStorageDb');
request.onerror = (event) => {
console.error(`Database error}`);
};
request.onsuccess = (event) => {
const db = request.result;
insertUser(db, valueRetrievedManuallyFromIndexDB);
};
}
test('login', async ({ page }) => {
await page.evaluate(setAuthInBrowser);
})
expect(await page.locator('body').innerText()).toContain('displayname'); // fails
});
Do you get any errors in console? Unless you have a beforeEach
method that does it, you need to load your signin page before page.evaluate(setAuthInBrowser
. That creates the Firebase database and object store in IndexedDB, which is what your insertUser
method updates. If the DB isn't there, you'll need to create it in insertUser
. I prefer to have it happen in the browser.
Here's my loginPage
fixture, showing the sequence of events. I call loginPage.loginUser
in a beforeEach
method, but in your test you could call such a method or have similar steps in the test before calling page.evaluate
.
export class LoginPage {
readonly page: Page;
readonly googleSignInButton: Locator;
constructor(page: Page) {
this.page = page;
this.googleSignInButton = page.locator('a', { hasText: /Sign in with Google/ });
}
async goto() {
await this.page.goto('/');
await expect(this.googleSignInButton).toBeVisible();
}
/**
* Logs in the user with cached storage credentials
*/
async loginUser(email = process.env.USER_EMAIL) {
await test.step('Log in with cached credentials', async () => {
const firebase = new FirebaseAuth();
const userInfo = await firebase.getUserInfo(email);
await this.goto();
await this.page.evaluate(firebase.setAuthInBrowser, { userInfo });
});
}
}
This is my minimal test to ensure just the login part is working:
test.beforeEach(async ({ loginPage }) => {
await loginPage.loginUser();
});
test('The Playwright Firebase plugin and app login are working', async ({ page }) => {
await page.goto(HttpRoutes.Reporting);
await page.waitForURL(`**/${HttpRoutes.Reporting}**`);
expect(page.url()).toContain(HttpRoutes.Reporting);
});
Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email [email protected].