Puppeteer 测试 - CdpElementHandle.click() 似乎不起作用

问题描述 投票:0回答:1

我正在尝试对 Puppeteer 的工作原理有一些基本的了解,并且正在努力奋斗。 我正在测试的应用程序可以在here找到。 单击“登录”按钮后,应用程序应重定向到 Spotify 并获得 AOuth 授权,以搜索 API 并在登录用户的帐户中创建和保存播放列表。 然而,我不认为我的测试点击了按钮,尽管它“找到”了它 - 它似乎在

headless: false
模式下没有做任何事情,并且肯定不会重定向到任何地方。测试当然也失败了。 如果我设法以某种方式解决这个问题,我是否能够在“测试模式”下获得令牌(抱歉我的表达很愚蠢,希望它足够清楚)?我无法想象能够做到这一点,因为 Puppeteer 必须“登录”Spotify,但一定有办法。 作为旁注,任何人都可以解释一下像
await page.waitForTimeout(HEADING_SELECTOR);
这样的表达式实际上是做什么的。如果我用有意义的东西替换参数,即 10000,我会收到超时错误。 字符串值实际上有什么作用? 谢谢。

const puppeteer = require('puppeteer');
const { expect } = require('chai');
const _ = require('lodash');
const globalVariables = _.pick(global, ['browser', 'expect']);


// puppeteer options
const opts = {
    headless: false,
    slowMo: 100,
    timeout: 10000
};

// expose variables
before(async function () {
    global.expect = expect;
    global.browser = await puppeteer.launch(opts);
});

// close browser and reset global variables
after(function () {
    browser.close();

    global.browser = globalVariables.browser;
    global.expect = globalVariables.expect;
});


describe('sample test', function () {

    // By default, Mocha tests have a 2 second timeout (which means that the test needs to be completed in 2 seconds).
    // You can increase it (in milliseconds) as follows:

    this.timeout(8000); // this test can take up to 5 seconds

    let page;

    before(async function () {
        page = await browser.newPage();
        await page.goto('http://localhost:3000');
    });

    after(async function () {
        await page.close();
    })


    // TESTS
    it('should work', async function () {
        console.log(await browser.version());
        expect(true).to.be.true;
    });

    it('should have the correct page title', async function () {
        expect(await page.title()).to.eql('Spotify Playlist Creator');
    });

    it('should have correct heading', async function () {
        const HEADING_SELECTOR = 'h1';
        let heading;

        page.waitForSelector(HEADING_SELECTOR)

        /*
        page.$eval takes two arguments - selector and pageFunction. 
        It runs a document.querySelector in the browser environment and passes the result to the pageFunction. 
        Finally, it resolves with the value returned by pageFunction. 
        In this case, we are just returning the text for h1 tag.
        */
        heading = await page.$eval(HEADING_SELECTOR, heading => heading.innerText);

        expect(heading).to.eql('Spotify Playlist Creator');
    });

    it('should not display ErrorModal', async function () {
        const ERROR_MODAL_SELECTOR = '.ErrorModal';

        page.waitForSelector(ERROR_MODAL_SELECTOR)

        // The method runs document.querySelectorAll within the page. If no elements match the selector, the return value resolves to []
        expect(await page.$$(ERROR_MODAL_SELECTOR)).to.be.deep.equal([])
    });

    it('should be displaying login button', async function () {
        const LOGIN_BUTTON_SELECTOR = 'button';
        let loginBtn;

        page.waitForSelector(LOGIN_BUTTON_SELECTOR);

        loginBtn = await page.$(LOGIN_BUTTON_SELECTOR)
        const btnText = await page.evaluate(loginBtn => loginBtn.textContent, loginBtn);

        expect(btnText).to.equal("Login to Spotify");
    });

    // DOES NOT WORK!!!
    it('should click login button', async function () {
        const LOGIN_BUTTON_SELECTOR = 'button';
        let loginBtn;

        page.waitForSelector(LOGIN_BUTTON_SELECTOR);

        loginBtn = await page.$(LOGIN_BUTTON_SELECTOR)

        await loginBtn.click();
        console.log(loginBtn, "button has been clicked")

        expect(page.url()).to.include("https://accounts.spotify.com/en/login?");
    });
})
javascript automated-tests mocha.js puppeteer chai
1个回答
0
投票

我先用Cypress达到了预期的效果:

cy.on("url:changed", (newUrl) => {
            expect(newUrl).to.contain([whatever-it-should-contain])

如果我没记错的话 Page.waitForNavigation() 方法在 Puppeteer 中也做了同样的事情。 我不是一个快乐的兔子,因为我浪费了几个小时来解决这个问题 - 我从来没有想到一个名为“waitForNavigation”的方法会等待页面导航到新的 URL...这当然完全是我的错。 正确的测试如下:

it.only('should click login button', async function () {
        const LOGIN_BUTTON_SELECTOR = 'button';
        let loginBtn;
        page.waitForSelector(LOGIN_BUTTON_SELECTOR);
        loginBtn = await page.$(LOGIN_BUTTON_SELECTOR)

        await loginBtn.click();

        await page.waitForNavigation();
        expect(page.url()).to.include("https://accounts.spotify.com/en/login?");
    });

© www.soinside.com 2019 - 2024. All rights reserved.