为什么 nodemailer 在 playwright 项目中不起作用?

Why nodemailer does not work in playwright project?

提问人:Aylin Naebzadeh 提问时间:11/16/2023 最后编辑:Aylin Naebzadeh 更新时间:11/16/2023 访问量:23

问:

我已经在我的 play wright 项目中实现了一个 reporter.ts 文件。我想在运行测试结束时向一些开发人员发送一封电子邮件。但是虽然我尝试了几种方法并阅读了模块的文档,但没有发送电子邮件,也没有显示任何错误。nodemailer

这是我的reporter.ts文件的完整代码:

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("\n\n");
        

        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("\n\n");
        
        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:\n\n${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;

输出:

(SepantaEnv) D:\ABDAL\sepanta\PlayWright>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:\ABDAL\sepanta\PlayWright>

我将非常感谢任何帮助,因为我被困在这个问题中大约一个星期。

JavaScript TypeScript 测试 Playwright Nodemailer

评论

0赞 esqew 11/16/2023
"没有发送电子邮件“您能否具体说明您使用哪些证据来做出此断言?是不是邮件没有出现在发送帐户的“已发送邮件”文件夹中?别的?
0赞 Aylin Naebzadeh 11/16/2023
是的,没错......[email protected]帐户的“已发送邮件”中没有电子邮件,[email protected]的“垃圾邮件”或“收件箱”中也没有来自此帐户的电子邮件。
0赞 Infern0 11/16/2023
sendEmail() 是异步函数,但您没有等待它。查看 playwright.dev/docs/api/class-reporter 等待reporter.onEnd(result);理解 from promise,因此您可以将 onEnd 声明为 async,并使用 await 或 return promise。
0赞 Aylin Naebzadeh 11/22/2023
我将其定义为异步。但问题并没有得到解决yet.@Infern0

答: 暂无答案