I have implemented a reporter.ts file in my play wright project. I want to send an email to some developers at the end of the running tests. But although I have tried several ways and read the documentation of nodemailer module, but no email is sent, and no error is also shown.
Here is my full code of reporter.ts file:
import { FullConfig, FullResult, Reporter, Suite, TestCase, TestResult, TestStatus, TestError } from "@playwright/test/reporter";
import * as fs from "fs"; // The node:fs module enables interacting with the file system in a way modeled on standard POSIX functions
import date from 'date-and-time';
import nodemailer from "nodemailer";
import cron from "node-cron";
import { spawn } from "child_process";
import { google } from 'googleapis';
import { OAUTH_CLIENTID,
OAUTH_CLIENT_SECRET,
OAUTH_REFRESH_TOKEN,
OAUTH_ACCESS_TOKEN,
REDIRECT_URL } from "./constant/authorization";
/**
* To run this file use the below command:
* npx playwright test --reporter=reporter.ts
*/
// Set up Auth2 client
const oAuth2Client = new google.auth.OAuth2(
OAUTH_CLIENTID,
OAUTH_CLIENT_SECRET,
REDIRECT_URL
)
// Set the access token
oAuth2Client.setCredentials({
access_token: OAUTH_ACCESS_TOKEN,
});
// Create the transporter using OAuth2 authentication
const transporter = nodemailer.createTransport({
service: 'gmail',
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
type: 'OAuth2',
user: '[email protected]',
clientId: OAUTH_CLIENTID,
clientSecret: OAUTH_CLIENT_SECRET,
refreshToken: OAUTH_REFRESH_TOKEN,
accessToken: oAuth2Client.getAccessToken(),
}
});
class MyReporter implements Reporter {
modifiedResults: { test: string; status: TestStatus; executionTime: number; errors: TestError[] }[];
constructor() {
this.modifiedResults = [];
}
onBegin(config: FullConfig<{}, {}>, suite: Suite): void {
console.log(`Execution of ${suite.allTests().length} tests`);
}
onEnd(result: FullResult): void | Promise<void | { status?: "passed" | "failed" | "timedout" | "interrupted" | undefined; } | undefined> {
console.log(`Execution finished with status of ${result.status}`);
// this.sendEmail();
const now = new Date(); // Get the current date and time
const dateStringFolder = date.format(now, 'YYYY-MM-DD');
const dateStringFile = date.format(now, 'YYYY-MM-DD-HH');
const folderPath = `pw_res_${dateStringFolder}`;
if (!fs.existsSync(folderPath)) {
fs.mkdirSync(folderPath);
}
const formattedResults = this.modifiedResults.map((test) => ({
title: test.test,
status: test.status,
errors: test.errors
}));
// console.log(`The formated result is: ${formattedResults}`);
// Format the test results in a more interpretable way
const formattedEmailContent = formattedResults
.map((result) => `Title: ${result.title}nStatus: ${result.status}nErrors: ${result.errors}`)
.join("nn");
const randomInt = Math.random();
fs.appendFileSync(`${folderPath}/test-result-${dateStringFile}.txt`, formattedEmailContent);
this.sendEmail();
console.log("HA HA HA!");
}
onTestBegin(test: TestCase, result: TestResult): void {
console.log(`Execution of ${test.title} started.`);
}
onTestEnd(test: TestCase, result: TestResult): void {
const now = new Date(); // Get the current date and time
const dateString = date.format(now, 'YYYY-MM-DD_HH-mm-ss'); // Format the date and time into a string
const execTime = result.duration;
const data = {
test: test.title,
status: result.status,
executionTime: execTime,
errors: result.errors
};
this.modifiedResults.push(data);
}
async sendEmail() {
console.log(this.modifiedResults);
// Extract the title and status of each test
const formattedResults = this.modifiedResults.map((test) => ({
title: test.test,
status: test.status
}));
// console.log(`The formated result is: ${formattedResults}`);
// Format the test results in a more interpretable way
const formattedEmailContent = formattedResults
.map((result) => `Title: ${result.title}nStatus: ${result.status}`)
.join("nn");
console.log(`The formated email content is: ${formattedEmailContent}`);
// Compose the email
const mailOptions = {
from: "[email protected]",
to: "[email protected]",
subject: "PlayWright Test Results",
text: `Test Results:nn${formattedEmailContent}`
};
console.log("---------------- send email ---------------")
// Send the email
await transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.error('Error sending email: ', error);
} else {
console.log('Email sent: ', info.response);
}
});
};
}
// Export the MyReporter class
module.exports = MyReporter;
The output:
(SepantaEnv) D:ABDALsepantaPlayWright>npx playwright test --reporter=reporter.ts
Execution of 2 tests
Execution of login started.
Execution of failed login started.
Execution finished with status of passed
[
{
test: 'failed login',
status: 'passed',
executionTime: 6754,
errors: []
},
{ test: 'login', status: 'passed', executionTime: 7141, errors: [] }
]
The formated email content is: Title: failed login
Status: passed
Title: login
Status: passed
---------------- send email ---------------
HA HA HA!
(SepantaEnv) D:ABDALsepantaPlayWright>
I will be really grateful for any help, since I am stuck in this problem for about one week.