What could be the reason of me not being able to access the Proxy of the CustomPage class in my test file? I get this error...
enter image description here
const puppeteer = require("puppeteer");
class CustomPage {
static async build() {
const browser = await puppeteer.launch({
headless: false,
});
const page = await browser.newPage();
const customPage = new CustomPage(page);
return new Proxy(customPage, {
get: function (target, property) {
return customPage[property] || browser[property] || page[property];
},
});
}
constructor(page) {
this.page = page;
}
getContentsOf(selector) {
return this.page.$eval(selector,el=>el.innerHTML);
}
}
module.exports = CustomPage;
const Page = require("./helpers/page");
let page;
beforeEach( async () => {
page = await Page.build();
await page.goto('http://localhost:5002');
});
afterEach(async () => {
await page.close();
});
describe("we started HomePage tests and...",() => {
test("can see blog create form", async () => {
const subscribeButton = await page.$eval(".subscribe-btn",el=>el.innerHTML);
expect(subscribeButton).toEqual("გამოწერა");
});
});
I don't know what exactly should I try to fix it.
The issue has to do with binding, as described in ES6 proxied class, access private property (Cannot read private member #hidden from an object whose class did not declare it). Proxy
getshould return a function that's bound to the instance you want to call it on:That said, red flags should be raised here--this is much too complicated and prone to confusing errors like the one you're already battling. Best case scenario, as a client of
CustomPage, if I call a function, I have no idea which instance is receiving the call.page.close()becomes impossible to call becausebrowser.close()is called instead. Even if the intended behavior occurs, the code will still be difficult to read.If you want to write an abstraction on the browser and/or page, don't do it prematurely. Wait until you have a need for it. If you do, try for something like a page object model from Playwright. In a POM, you don't expose
pageorbrowserto the caller at all, enforcing all test actions occur on a higher level based on the specific set of actions and elements for a page. This ensures your tests are written at a consistent level of abstraction, as the caller is unable to access lower-levelpageandbrowserfunctions unless the POM has explicitly exposed them.