Issue with equired with Page Object model design with Playwright test - javascript

Below is the code for the test file
const { test, expect } = require('#playwright/test')
const HomePage = require('./pageobejcts/HomePage')
test.beforeEach(async ({ page }) => {
await page.goto("https://automationexercise.com/");
})
test('Navigate to Login', async ({ page }) => {
let homepage = new HomePage(page);
homepage.navigateToLoginSignUp();
await expect(page.locator('//div[#class="signup-form"]/h2')).toBeVisible();
await page.screenshot({ path: 'screenshot.png' });
//await expect(page.locator('//img[#alt="Website for automation practice"]')).toBeVisible;
})
And below is code for one of the Screen class
class HomePage {
constructor(page) {
this.page = page;
this.signupLnk = '//a[#href="/login"]';
}
async clickSignupLink() {
await this.page.click(this.signupLnk);
}
}
module.exports = HomePage;
Now the above code works fine. But in the Screen Class, as there is no Page object defined, there is no auto-complete/documentation available when using the Page methods.
eg On writing page.click(), the IDE does not recognize the click function and does not suggest the correct parameters
Is there a way to resolve this?

If I understand Your question correctly this should work:
let homepage = new HomePage(page);
await homepage.page.click('selector')
Also I suggest to use Fixtures in combination with page object model.

await this.signupLnk.click();
You can call the locator directly and call the click function on it.

add this to class file -
/**
#param {import('#playwright/test').Page} page
*/

Related

Dynamic Page Render On Demand Next Js

So, I am working on a simple Next.Js app. It's just a Lyrical Page but I'm running onto some issues. I'm new to Next.Js and this is my first project. So, here is my problem:
I have a dynamic set of pages/folders which looks like this:
songs (empty folder)
[singer] (child of songs containng just an index.jsx)
[title] (child of [singer] containing another index.jsx)
Now in my [title] - index.jsx im rendering a simple page providing lyrics for a specific song.
My problem is that I want to count views (every time someone opens this page) for each song sepertly. I have the following code:
export const getStaticProps = async (context) => {
const res = await fetch(`${process.env.PROXY}api/lyrics/post/${encodeURIComponent(context.params.title)}`);
const data = await res.json();
const send = await fetch(`${process.env.PROXY}api/lyrics/views/${data.post._id}`);
return {
props: {
data: data.post,
message: 200
}
}
}
export const getStaticPaths = async () => {
const res = await fetch(`${process.env.PROXY}api/lyrics/getAll`);
const data = await res.json();
const paths = data.all.map((name) => ({ params: { singer: name.singer.toString(), title: name.title.toString() } }));
return {
paths: paths,
fallback: 'blocking'
}
}
The problem is I know getStaticProps renders only on build time, however, I want to render every time so that I can count the views with my send variable.
Can someone please help me figure this out? Any help will be appreciated!

how to import async modules with JS

Maybe i asked wrong question.
i'm trying to test some site, and have this throw in terminal
terminal output
it's obvious, that function returns uuid after it was called in code.
it work's normaly, when i take element right in code, so the reason, i think, in uncorrect import
here's my code :
file.js
describe('final homeTask', () => {
it('firstassigment', async () => {
let mainPage = require('../page/main.pageHW.js')
await browser.url('https://github.com/')
let signUpButton = await mainPage.topSignUpBtn()
await signUpButton.click()
})
})
main.pageHW.js
class MainPage {
get topSignUpBtn () { return $('a.btn-mktg:nth-child(1)') }
}
module.exports = new MainPage()
It is a problem with Javascript, not about webdriver, you are using a property in the MainPage class:
class MainPage {
/// The get word make it a property
get topSignUpBtn () { return $('a.btn-mktg:nth-child(1)') }
}
module.exports = new MainPage()
That means you DON'T need parentheses to use it, so, replace:
let signUpButton = await mainPage.topSignUpBtn()
By
let signUpButton = await mainPage.topSignUpBtn;
Also, the property doesn't need the await clause.
If you want more info you can check this link.

Protractor can't perform click on <li> tag

I'm tring to make an e2e test of my application but I can't perform click on search engine.
This is the example I want to try to "click" on the first element but protractor stuck on the image below :
The website that I'm taliking about is this : https://rent.decathlon.it/
The result is a timeout error, so the element is not clicked.
This is the protractor code :
import { AppPage } from './app.po';
import {browser, by, element, logging} from 'protractor';
import {SearchBoxWizard} from '../elements/searchbox_wizard';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('shoud open select item', async () => {
await page.navigateTo();
browser.sleep(500);
const searchBoxWizardElements = new SearchBoxWizard();
await searchBoxWizardElements.getLocationInput().click();
await searchBoxWizardElements.getLocationInput().clear();
await searchBoxWizardElements.getLocationInput().sendKeys('Milano');
await browser.sleep(500);
element(by.css(`.autocomplete-search > ul > li:nth-child(1) > span`)).click();
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});
Someone have an idea of why?
I'm using this stack :
Angular 8
protractor 5.6 or 7
Karma 4.1
Jasmin 3
Regards
EDIT :
I notice very strange behavior, If I check if body is displayed, protractor can't see it, this is the code...
it('shoud open select item', async () => {
await page.navigateTo();
const searchBoxWizardElements = new SearchBoxWizard();
const cookiePolicy = new CookiePolicy();
await cookiePolicy.getAcceptCta().click();
await searchBoxWizardElements.getLocationInput().click();
await searchBoxWizardElements.getLocationInput().clear();
await searchBoxWizardElements.getLocationInput().sendKeys('Milano').then(
async _ => {
await browser.sleep(2500);
await element(by.css('body')).isDisplayed();
});
});
I think it is something like "loosing" app focus... I don't know...
Have you got any idea?
Regards
it is definitely a google api. I checked that. Requests are coming back from https://maps.googleapis.com/maps/api/place/js
You missed await in many places. You need to read about promises and way to handle is with await
browser.sleep needs await
.click() needs await

How to use expo-background-fetch to fetch a specific url every 60 seconds?

I have tried almost any example provided in docs but I can't run it.
I want to make a request to a specific url with axios (or fetch method) every 60 seconds and process the data in the background. In other words I want something common like:
this.getPageInterval = setInterval(() => {
const json = await (await fetch(this.fetchURL)).json();
...// etc
}, 60000)
can happen when the app is in background.
my console.log says 'task registered' but it feels like this block of code never triggers(global scope):
BackgroundFetch.setMinimumIntervalAsync(5);
const taskName = 'test-background-fetch';
TaskManager.defineTask(taskName, async () => {
console.log('background fetch running');
try {
const receivedNewData = await (await fetch(this.fetchUri)).json();
console.log('receivedNewData', receivedNewData)
return receivedNewData ? BackgroundFetch.Result.NewData : BackgroundFetch.Result.NoData;
let isRegistered = await TaskManager.isTaskRegisteredAsync(taskName);
console.log("isRegistered: ", isRegistered);
} catch (error) {
return BackgroundFetch.Result.Failed;
}
console.log("BackgroundFetch.Result.NewData", BackgroundFetch.Result.NewData);
return BackgroundFetch.Result.NewData;
});
and in my class component:
await BackgroundFetch.registerTaskAsync(taskName, {
setMinimumIntervalAsync: 5,
stopOnTerminate: false
});
await BackgroundFetch.setMinimumIntervalAsync(5);
alert('task registered');
console.log('task registered');
It seems you're not registering your task in your class component. Is taskname defined as 'test-background-fetch' in your component? You need to call exactly the same task name.
Also some phones are somewhat problematic with background tasks. I never tried it on expo, but on React Native some brands had to go through some extra setup.
Also note that in the documentation it says it only works when backgrounded. Terminated apps wont run the background function.

Puppeteer Page Object Model with browser and page put apart from main

I'm trying to put in a class the puppeter call, the browser object, and the page object. But I'm being unable to use it when using the Page Object Model. Page members are undefined.
In every example that I've found I always seen the call to puppeteer and the browser and page object within the main function. I guess that's a problem with context access.
But it's possible to archieve what I'm looking for and still be able to use at least the page object within Page Object files ?
main.mjs
import Browser from './browser.mjs'
import HomePage from './HomePage.mjs'
async function main () {
const browser = new Browser();
const homePage = new HomePage(browser.page);
await homePage.open();
console.log(await homepage.getTitle());
await browser.close();
}
main();
browser.mjs
class Browser {
constructor() {
return this.main(); // I know, that's ugly
}
async main() {
this.browser = await puppeteer.launch({
headless: false,
});
this.page = await browser.newPage();
return this.browser,this.page
}
}
export default Browser
homepage.mjs
class HomePage {
constructor(page) {
this.page = page;
}
async open() {
this.page.goto('http://www.contoso.com');
}
async getTitle() {
return this.page.title();
}
}
export default HomePage
return this.browser,this.page
This returns the browser. If you want to access browser and page, you should return this only. Your code should look like below.
return this
You can access browser, page and everything between from that object.

Categories