Thanks for watching this rather "hefty" TypeScript live-coding session. 🦝 If you want to check the final code, it's available on GitHub: github.com/checkly/playwright-examples/#apply-playwright-test-steps-with-typescript-decorators
Comparing it to the times of spinning up a browser, loading pages and waiting for UI elements to appear, the few millisecond to wrap class methods shouldn't matter. :)
Thanks for this!!! I was using it in Python. I have a question on using expect methods in Page Object Model. Why do we use it here, instead these can be used in test script file. Don’t you think this would be the best practice?
Great question. :) I don't think there's a silver bullet or "the one single best practice" when it comes to POMs and how to structure them. In this video I had the assertions in the POM because it made the test more readable for the video. 🤷 :)
Can we set method argument values inside decorator, that was applied for that method, like this: @step(`Add product '${ product.name }' to card`) async addToCard(product: Product){ // adding product logic... }
That's correct. 👆 If `product` is available in the POM scope then it works easily. But I assume you want to pass arguments into your POM methods and reuse these. I don't think there's a "not hacky" way of achieving this. That said, I've spent a moment and hacked something together but I don't think it's great 👉 gist.github.com/stefanjudis/2c141224a9584f48c83a245c14653d7c Downsides are: - you have to rely on `this` - you have to always (!) use an options object as first method param - it's very nasty JS/TS So yeah, I would advice against hacking this together. 😅 Great question, though. 👍
@@ChecklyHQ Good catch, using "options" object, I was just thinking how reusable would be this approach with decorators inside POMs. Meaning, that we will have to have some kind of compromise in a description, by overly generalizing it, if we, let's say, using "ordinary" method parameters. I was also thinking, that first approach, that uses test.step inside methods of POM, makes it configurable for whatever data your methods accepts and therefore what approach is the best one depends on a project needs and personal preferences.
Hai Stefan, This is an excellent use of TypeScript in Playwright. Thank you for sharing this. The current implementation of Steps is complex, but I'm willing to put in the effort to add the steps because of its benefits. This video is much anticipated. Once again, thank you. Can you consider integrating Playwright with Mountebank for future videos?
Heyoooo. :) I haven't used Mountebank, but we're trying to keep things close to Checkly monitoring practices. So, unfortunately, it's unlikely we will share something not working in the Checkly platform.
Hi Stefan, quick question: would you define the step function in every single pom class or would you create a new class exporting the step function and import it into every pom class? Or something else entirely? Thank you
Heyoooo. :) I'd keep things in the public POM methods. But there are situations where I additionally group things in the actual test cases. I usually decided to add more grouping when the test if overly complex. I hope this makes sense. :)
Sorry if I missed that... But to to click some second "Button" for example it there can be or sometimes not present. It's dynamically changed! So the task is: If we have button - click, if haven't - skip and go next
@@vitaliy6490 Hah! That's great then. Because you wrote "Sorry if I missed that..." I thought you were referring to something in the video. :) But I still need some more information, because I don't understand the question or the problem. 🫣
This is really great example to use decorator !! I have one request having 200+ test and we want single login & use browser cookies to run rest all test cases . how efficiently we can design this stuff so that re use it & if application session gone then script can check & re validate or say save the cookies again for next test cases .
are there conditions to use this in ts config or something? because I keep get errors on the type of function when I put the decorator above a function in a page
There are no special ts config settings. You can find the explained source code (including config) here: github.com/checkly/playwright-examples/tree/main/test-step-decorators
Unfortunately, that's correct right now (I didn't say that Checkly supports them, though). When I checked Checkly compatibility, they worked fine and were supported when you define / use decorators in a single file. For the example shown, there seems to be a bug in the Checkly CLI bundling, and I filed a bug report. It might be resolved soon.
Hello I am trying to apply your code but is not working I have problem at "this" I have tried to write the code inside a class or into a ts file and is the same error 'this' implicitly has type 'any' because it does not have a type annotation.ts(2683) Can you help me a bit please?
Hello, unfortunately it's almost impossible to help out here in the RUclips comments. Please check the example code with the working demo code: github.com/checkly/playwright-examples/tree/main/test-step-decorators
@@dorhaalex5354 Unfortunately, there's little I can do then. I have the same code running and working in front of me. Please clone the repo (github.com/checkly/playwright-examples/tree/main/test-step-decorators), install everything, and check if it runs. Usually, there's a mistake somewhere when working along the video. :)
Ouch... I didn't think of this. Could you split things and use a different tsconfig only for your tests? 👉 playwright.dev/docs/release-notes#--tsconfig-cli-option
I've never used Gherkin's - Cucumber and unfortunately am still confused about it. But Playwright's test teps (with or without decorators) allow you to put a "custom label" on code sections. They're not defining any behavior. Hope this helps. :)
Please check the example implementation on GitHub. github.com/checkly/playwright-examples/tree/main/test-step-decorators Unfortunately, it's almost impossible to debug things YT comments. :)
Thanks for the idea ! I tried , but I received undefined for the step in report : Select Item From List (undefined) @ChecklyHQ could you help to fix it ?
Unfortunately, we can't offer debugging sessions but you can find a working example on GitHub. github.com/checkly/playwright-examples/tree/main/test-step-decorators
When I run a method that has a preceding @step decorator, whenever I pass something to it as an argument, it's resolved to an object instead of the actual argument type. Example: pass a string variable to a method that uses the @step decorator ``` @step("Fill in Password") async fillPassword(password: string) { await this.page.locator("#password").fill(password); } ``` used in a test.spec.ts ``` await signUpModal.fillPassword("Test1234!"); ``` will result in: ``` Error: locator.fill: value: expected string, got object at ../page-objects/modals/sign-in-or-sign-up.ts:73 71 | @step("Fill in Password") 72 | async fillPassword(password: string) { > 73 | await this.page.locator("#password").fill(password); | ^ 74 | } ``` Sorry that I'm putting this as a comment, but no one has helped in the Typescript Discord, I couldn't find a Checkly Discord and didn't want to ask in Playwright Discord, since it's a TS issue really. The same code will work when I remove the @step decorator (effectively the step function wrapper), so I'm assuming it's got something to do with asynchronicity but no idea how I would solve this since I'm not quite there yet programming skill wise. Will probably have to remove all of my @step decorators in the meanwhile which is ultra frustrating. Any help would be highly appreciated. If I console.log the `args` passed to the `replacementMethod(...args)`, I get args:Test1234! type of args:object AI says: The reason you're seeing args as an object even though it holds a string value is because it's captured as an array of arguments by the spread syntax ...args. but you don't want to see the nasty solution
You forget to paste the most important detail - the decorator function itself. You're correct that YT comments aren't the best place for this discussion, but please check the implementation of the video. It pretty much covers your use case: github.com/checkly/playwright-examples/blob/main/test-step-decorators/tests/poms/playwright-page.ts#L26-L31
I'm just guessing, but looking at your error, you might have this line wrong? github.com/checkly/playwright-examples/blob/main/test-step-decorators/tests/base.ts#L31
@@ChecklyHQ When I first started taking on your code into mind, I had copied the decorator method from your repository but apparently had implemented it the wrong way. Before, I had the decorator method sit inside of the pom itself at the bottom and wasn't using any custom fixtures, maybe that was the issue. Anyway I've taken a look at your repository and reorganized my code to have a base fixture containing both the pom and exporting the step function. Still confused about to why it's working this way, but super thankful for your help and happy that it's working now. Have a great start into the week, Stefan 🦝🙏
@@ChecklyHQ I tried awaiting that `target.call(...)` but it didn't really help (which was very confusing) I've gotten a much better idea of what's going on inside of that function now though. Unfortunately I'm unable to describe what exactly the issue was control flow wise and why it is working now. When I can, I definitely will make sure to write an explanation. Organizing it the way you did helped fix the issue though. Wish we had a Checkly Discord ngl.
Thanks for watching this rather "hefty" TypeScript live-coding session. 🦝
If you want to check the final code, it's available on GitHub: github.com/checkly/playwright-examples/#apply-playwright-test-steps-with-typescript-decorators
I've watched all of your videos, and they are incredibly informative. Thank you so much for sharing them!
Glad you like them and thanks for watching! 😊
This is brilliant and timely for us. Thanks for the video!
Glad it was helpful!
Nice video ! Would be worth to do the same with tags and annotations
This looks cool! thanks for sharing.😎
Very useful. Thanks for sharing
Sir, this is what i'm looking for, Thanks a lot.
I hoped you'd say that. :)
Your videos are so useful for me. Thanks for sharing.
Thank you! 💙 Happy to hear that the videos are valuable. 🦝
awesome, awesome, awesome, awesome, awesome, awesome, awesome, awesome, awesome, awesome, awesome, awesome!!!!
Thank you very much for such videos! Keep going! You are doing this great!
Thank you! 💙
Thanks! Will implement it immediately!
Great content as always!
Really useful. Thank for this video!
Thanks, you've presented this wonderfully :)
looks really cool ! won't using a declarator increase the time for tests?
Comparing it to the times of spinning up a browser, loading pages and waiting for UI elements to appear, the few millisecond to wrap class methods shouldn't matter. :)
Thanks for this!!! I was using it in Python.
I have a question on using expect methods in Page Object Model. Why do we use it here, instead these can be used in test script file. Don’t you think this would be the best practice?
Great question. :)
I don't think there's a silver bullet or "the one single best practice" when it comes to POMs and how to structure them. In this video I had the assertions in the POM because it made the test more readable for the video. 🤷 :)
Thank you for another awesome video!
Thanks for watching!
Can we set method argument values inside decorator, that was applied for that method, like this:
@step(`Add product '${ product.name }' to card`)
async addToCard(product: Product){
// adding product logic...
}
if product is already defined outside of that scope, sure.
That's correct. 👆 If `product` is available in the POM scope then it works easily.
But I assume you want to pass arguments into your POM methods and reuse these. I don't think there's a "not hacky" way of achieving this. That said, I've spent a moment and hacked something together but I don't think it's great 👉 gist.github.com/stefanjudis/2c141224a9584f48c83a245c14653d7c
Downsides are:
- you have to rely on `this`
- you have to always (!) use an options object as first method param
- it's very nasty JS/TS
So yeah, I would advice against hacking this together. 😅 Great question, though. 👍
@@ChecklyHQ Good catch, using "options" object, I was just thinking how reusable would be this approach with decorators inside POMs. Meaning, that we will have to have some kind of compromise in a description, by overly generalizing it, if we, let's say, using "ordinary" method parameters. I was also thinking, that first approach, that uses test.step inside methods of POM, makes it configurable for whatever data your methods accepts and therefore what approach is the best one depends on a project needs and personal preferences.
@@alexpoyan5788 Yeah 100%. It's the usual "it depends" and a matter of trade-offs. 👍
Hai Stefan,
This is an excellent use of TypeScript in Playwright. Thank you for sharing this. The current implementation of Steps is complex, but I'm willing to put in the effort to add the steps because of its benefits. This video is much anticipated. Once again, thank you. Can you consider integrating Playwright with Mountebank for future videos?
Heyoooo. :) I haven't used Mountebank, but we're trying to keep things close to Checkly monitoring practices. So, unfortunately, it's unlikely we will share something not working in the Checkly platform.
Hi Stefan, quick question: would you define the step function in every single pom class or would you create a new class exporting the step function and import it into every pom class? Or something else entirely? Thank you
Heyoooo. :) I'd keep things in the public POM methods. But there are situations where I additionally group things in the actual test cases. I usually decided to add more grouping when the test if overly complex. I hope this makes sense. :)
Sorry if I missed that... But to to click some second "Button" for example it there can be or sometimes not present. It's dynamically changed! So the task is: If we have button - click, if haven't - skip and go next
I'm not sure I understand. How does this relate to this video? 😊
@@ChecklyHQ You said, if we have some question what you can observe in the next video - leave comments)
@@vitaliy6490 Hah! That's great then. Because you wrote "Sorry if I missed that..." I thought you were referring to something in the video. :)
But I still need some more information, because I don't understand the question or the problem. 🫣
This is really great example to use decorator !! I have one request having 200+ test and we want single login & use browser cookies to run rest all test cases .
how efficiently we can design this stuff so that re use it & if application session gone then script can check & re validate or say save the cookies again for next test cases .
Thank you! It sounds like you're looking for `storageState`? 👉 ruclips.net/video/nSHPCLUwwVk/видео.html
Very helpful!
Great, thanks a lot 👍
Thanks
are there conditions to use this in ts config or something? because I keep get errors on the type of function when I put the decorator above a function in a page
There are no special ts config settings. You can find the explained source code (including config) here: github.com/checkly/playwright-examples/tree/main/test-step-decorators
awesome !!!
What if we need to use a values in steps? how to workaround it?
Can you explain the exact problem? :) Can't you pass values to the method?
nice, but the Checkly tool is not supported the test.step with class decorators
Unfortunately, that's correct right now (I didn't say that Checkly supports them, though).
When I checked Checkly compatibility, they worked fine and were supported when you define / use decorators in a single file.
For the example shown, there seems to be a bug in the Checkly CLI bundling, and I filed a bug report. It might be resolved soon.
Hello
I am trying to apply your code but is not working
I have problem at "this"
I have tried to write the code inside a class or into a ts file and is the same error
'this' implicitly has type 'any' because it does not have a type annotation.ts(2683)
Can you help me a bit please?
Hello, unfortunately it's almost impossible to help out here in the RUclips comments. Please check the example code with the working demo code: github.com/checkly/playwright-examples/tree/main/test-step-decorators
@@ChecklyHQ I did it, is the same code
I have placed it in the same files that you did and I have this error that I have mentioned
@@dorhaalex5354 Unfortunately, there's little I can do then. I have the same code running and working in front of me. Please clone the repo (github.com/checkly/playwright-examples/tree/main/test-step-decorators), install everything, and check if it runs. Usually, there's a mistake somewhere when working along the video. :)
Unfortunatelly, this causes an error in case if tsconfig has ExperimentalDecorators set to true :(
Ouch... I didn't think of this. Could you split things and use a different tsconfig only for your tests? 👉 playwright.dev/docs/release-notes#--tsconfig-cli-option
Its like gherkin - cucumber?
I've never used Gherkin's - Cucumber and unfortunately am still confused about it. But Playwright's test teps (with or without decorators) allow you to put a "custom label" on code sections. They're not defining any behavior. Hope this helps. :)
good one
Thx!
Wonderfull!
cool....
This is great for class users in POM. Not something that would lead me to using class approach instead of "normal" object based
please make tutorial for playwright + cucumber sir
Please make a video on code coverage
Can you be a bit more explicit? What would you like to see? :)
I got this error when I use @step on func that receives variable
Error: locator.fill: value: expected string, got object
@step()
async fillUserName(userName: string) {
await expect.soft(this.userNameInput).toHaveAttribute('placeholder', 'Username');
await this.userNameInput.fill(userName);
await allure.parameter("User name", userName);
logger.info('The username is filled with: ' + userName);
}
Please check the example implementation on GitHub. github.com/checkly/playwright-examples/tree/main/test-step-decorators Unfortunately, it's almost impossible to debug things YT comments. :)
@@ChecklyHQ nevermind, it's my mistake i forgot the three dots before args
@@ChecklyHQ another question, is there way that I can use the step in the test file? and not in the POM
Thanks for the idea !
I tried , but I received undefined for the step in report : Select Item From List (undefined)
@ChecklyHQ could you help to fix it ?
Unfortunately, we can't offer debugging sessions but you can find a working example on GitHub. github.com/checkly/playwright-examples/tree/main/test-step-decorators
Just change ${this.name} to ${this.constructor.name}
When I run a method that has a preceding @step decorator, whenever I pass something to it as an argument, it's resolved to an object instead of the actual argument type.
Example: pass a string variable to a method that uses the @step decorator
```
@step("Fill in Password")
async fillPassword(password: string) {
await this.page.locator("#password").fill(password);
}
```
used in a test.spec.ts
```
await signUpModal.fillPassword("Test1234!");
```
will result in:
```
Error: locator.fill: value: expected string, got object
at ../page-objects/modals/sign-in-or-sign-up.ts:73
71 | @step("Fill in Password")
72 | async fillPassword(password: string) {
> 73 | await this.page.locator("#password").fill(password);
| ^
74 | }
```
Sorry that I'm putting this as a comment, but no one has helped in the Typescript Discord, I couldn't find a Checkly Discord and didn't want to ask in Playwright Discord, since it's a TS issue really.
The same code will work when I remove the @step decorator (effectively the step function wrapper), so I'm assuming it's got something to do with asynchronicity but no idea how I would solve this since I'm not quite there yet programming skill wise.
Will probably have to remove all of my @step decorators in the meanwhile which is ultra frustrating. Any help would be highly appreciated.
If I console.log the `args` passed to the `replacementMethod(...args)`, I get
args:Test1234!
type of args:object
AI says:
The reason you're seeing args as an object even though it holds a string value is because it's captured as an array of arguments by the spread syntax ...args.
but you don't want to see the nasty solution
You forget to paste the most important detail - the decorator function itself. You're correct that YT comments aren't the best place for this discussion, but please check the implementation of the video. It pretty much covers your use case: github.com/checkly/playwright-examples/blob/main/test-step-decorators/tests/poms/playwright-page.ts#L26-L31
I'm just guessing, but looking at your error, you might have this line wrong? github.com/checkly/playwright-examples/blob/main/test-step-decorators/tests/base.ts#L31
@@ChecklyHQ When I first started taking on your code into mind, I had copied the decorator method from your repository but apparently had implemented it the wrong way. Before, I had the decorator method sit inside of the pom itself at the bottom and wasn't using any custom fixtures, maybe that was the issue.
Anyway I've taken a look at your repository and reorganized my code to have a base fixture containing both the pom and exporting the step function. Still confused about to why it's working this way, but super thankful for your help and happy that it's working now. Have a great start into the week, Stefan 🦝🙏
@@ChecklyHQ I tried awaiting that `target.call(...)` but it didn't really help (which was very confusing)
I've gotten a much better idea of what's going on inside of that function now though. Unfortunately I'm unable to describe what exactly the issue was control flow wise and why it is working now. When I can, I definitely will make sure to write an explanation. Organizing it the way you did helped fix the issue though. Wish we had a Checkly Discord ngl.
@@pokemokemon Well - happy it's resolved. 🎉 And we do have a Slack (no discord, unfortunately) 👉checklyhq.com/slack
Happy testing and monitoring!
It's very useful! Thanks man.
Glad to hear that!