How do you test whether your websites are working well?
Unit tests are great, but for web apps, the number of pieces that have to click together just so are many.
You have databases, server code, such as your Flask app, server templates like Jinja, CSS, JavaScript, and even deployment topologies.
Think Nginx and UVicorn.
Unit tests won't cover all of that integration, but Playwright does.
Playwright is a modern Pythonic take on testing web apps using code driving a browser core engine to interact with web apps the way real users and API clients do.
I think you'll find a lot to like here.
And we have Pandy Knight from Automation Panda here to break it down for us.
This is Talk Python to Me, episode 369, recorded May 12, 2022.
Welcome to Talk Python to Me, a weekly podcast on Python.
This is your host, Michael Kennedy.
Follow me on Twitter where I'm @mkennedy and keep up with the show and listen to past episodes at talkpython.fm.
And follow the show on Twitter via at Talk Python.
We've started streaming most of our episodes live on YouTube.
Subscribe to our YouTube channel over at talkpython.fm/youtube to get notified about upcoming shows and be part of that episode.
This episode is sponsored by Microsoft for Startups Founders Hub.
Check them out at talkpython.fm/founders hub to get early support for your startup.
And it's brought to you by Compiler from Red Hat.
Listen to an episode of their podcast as they demystify the tech industry over at talkpython.fm/compiler.
Transcripts for this and all of our episodes are brought to you by Assembly AI.
Do you need a great automatic speech to text API?
Get human level accuracy in just a few lines of code.
Visit talkpython.fm/assemblyai.
Hello, Andy.
Hey, what's going on?
What's up?
Man, it's great to catch up with you.
Oh, thank you.
You as well.
It's been a while.
Actually, the last time that we got to meet up, we were chilling at the Pi Bay, right?
I believe so.
Pretty far from both of our places.
But what a cool place to meet.
Outside at a food cart conference in San Francisco.
That was one of the best days of 2021.
It was incredible.
It really was.
And I got to tell you, I think more conferences should follow this style.
I know if you got a conference in Minnesota in the winter, you probably can't have it outside.
But boy, what a neat way to have a conference in the age of COVID where people felt comfortable.
And honestly, forget COVID.
I would have loved to go to this regardless, but it just works even better because of it.
Oh, yeah.
I'm looking forward to going back this year in September.
Oh, yeah.
It's going to be epic.
Okay.
Anyway, that was really great to meet you there.
And now we're here to talk about testing.
It's really, you know, what a surprise that you're on the show to talk testing in Python.
Who would have thought of all people?
Yeah.
And people may know you from your Automation Panda work and blog and stuff like that, right?
So let's get started with your story.
How do you get into programming in Python?
And maybe just kick it off by talking about Automation Panda.
It's maybe a good place to set the stage.
Sure.
So I'll start with how Python, then I'll talk about why Automation Panda.
So I first started programming Python in high school.
This was around 2005.
I think Python 2.3 was the new version.
I was taking a survey of programming languages course.
We did a whole bunch of things.
And the instructor really liked Python.
So I picked it up a little bit.
Nice.
Didn't do much other than toy around.
Then I didn't do anything with Python until about 2015, when I joined a new company in my
area called Max Point, and their three languages were Java, C#, and Python.
And so I picked up Python and I really, really, really loved it again.
And that's when I went heads down into it.
I've spoken my first Python conference.
It was PyData Carolinas 2016, right in my backyard in Durham.
IBM was hosting it.
Yeah.
Then I attended PyCon 2018, and the rest was history.
I think a lot of people out in the audience listening, many of them have never been to
either a regional or near international conference, PyCon.
And so many people I talked to are like, I can't, I didn't think I was really good enough
to go or experienced enough to go or whatever.
And then they say, but I went and it was amazing.
And now I feel so much more part of the community, right?
Like I just want to encourage people to, you know, like it sounds like you went there and
you're like, oh my gosh, I forgot how cool this place was, this ecosystem was.
And like, I'm in.
Absolutely.
I mean, that's one of the best ways to engage the Python community.
Find your local meetup, find your regional conference or attend the biggins.
Yeah.
And unfortunately, there are people who are far away from any of those, but there's really
good online meetups.
Like I was just on the PyIndie one and they've, they're doing a hybrid now with the Six Feet
Up folks.
And it's like, they've got their, their real in-person meetup, but then you can participate
and you're up on the screen with the group and whatnot.
So there's still ways to do it.
Even if you feel like, well, I live in small town outside of the small town that has no meetup,
right?
I'm the one Python person that I possibly know.
It's still an option.
Absolutely.
Okay.
So you dive in, get into it.
And you've basically been, been working in it on and off in different aspects for quite
a while now.
Indeed.
I consider Python my favorite programming language.
Funny fact, until my current job from about 2016 through 2021, my main programming language
at work was actually C#.
And so people would ask me, so what do you do with Python at work?
I say nothing.
And they think I'm joking.
I'm like, I'm more of a polyglot.
One can dream, but no, it is not true.
I don't know.
Yeah.
I mean, I do Java, JavaScript, Python, C#, you name it.
Way long ago, I did test automation in Perl for a couple of years.
That was fun, quote unquote.
I'm going to write a test regular expression to test the regular expression.
Oh my gosh.
Sorry.
I didn't really give you flashbacks.
It's all right.
That is the one gem that's buried in Perl, I would say.
I mean, Perl, every language has strengths and weaknesses.
Perl strength is reg X by far.
Yeah, sure.
Yeah.
Anytime I hear people talking about how much they use Perl or love Perl, it's got a really
strong text understanding element to what they were doing.
Mm-hmm.
Nice.
Well, you spoke about your jobs and doing the C# thing.
And I don't think that that's necessarily that big.
I don't think it's a negative.
You know, there's tons of people who they go to work and work in one language and then
they maybe come back and they love Python or vice versa.
Maybe they do Python and they love JavaScript.
I don't know.
We could get them help.
Just kidding.
But I know that for a lot of people, the dream is like, how do I do Python full time?
For now, it's a hobby.
But how do I like, I'm writing a blog, I'm doing some projects, but I want to do that as
my job.
Right.
So yeah, you kind of made that transition again, in a sense.
Yep.
Now being a developer advocate, I play with all the tools at the sandbox.
Yeah, that's awesome.
So tell us about what you're doing now.
Sure.
So I'm a developer advocate at a company called Apple tools.
Apple tools focuses on automated visual testing.
So if I got this right, there you go.
You got it.
Yeah.
Some people think I work at Apple.
It's like, no, no, no.
Apple tools.
A-P-P-L-I tools.
I'll put it in the show notes.
Sure, sure.
And so the premise is a lot of traditional functional testing is either your manual tester
banging on a keyboard, looking and clicking through.
Or if you're doing automation, you're scripting it, right?
With a tool like Playbrite or Cypress or Selenium WebDriver, whatever.
They're all good tools.
But when you're using a browser automation tool, typically you're faking like the clicks
and the typing.
And then you're scraping the DOM of the page to get things like text or attributes of HTML
tags or classes.
And you're doing some sort of assertions on those.
Right.
Sometimes as JavaScript, like a view front end, you just get like handlebars back.
Oh, well.
Nothing.
Yeah.
Or you got to do a little bit, something more complicated to scrape it.
But still, you're just like comparing text, right?
Exactly.
What about CSS?
What about visuals?
What about JavaScript events being linked up?
Exactly.
And so in that sense, the assertions you're doing are really a bare minimal validation of
the page.
The way I like to describe it is most traditional automated scripts will work if you rip the entire
CSS off the page.
It would look butt ugly, but your test scripts will go through.
So the question is, is that really proving that it works?
From a human aspect, no.
You would expect to make sure that things like your layout are good, that your buttons are
there, that your text is aligned.
All the colors are right.
And so that's where automated visual testing comes in, right?
That you would take snapshots of different views of your web or mobile apps, whether it's
a full page, whether it's a section of a page.
And then every time you make changes, you run the tests again, and they'll take checkpoint
comparisons to point out, here's what has changed.
And then you as the tester can decide, is that good or bad?
Kind of a visual diff, like an image diff, and then go from there.
Yep.
It's a little bit stronger than just like a pixel to pixel comparison, right?
Because if you had a padding shift by two pixels, all of a sudden everything's blown up, right?
Apple tools uses.
Yeah, exactly.
Like if it has the time of day up there and the time it goes from like nine to 10, it'll
shift everything a little bit.
Text changes like that too.
So what Apple tools does is it uses visual AI to really pick out the things that would be
noticeable to a human eye.
So if you have a small shift, not a big deal.
You can set ignore regions, like for certain text areas, like it's the time of day or those
kinds of things.
So you can really hone these visual assertions that you're making.
Other thing you can do is because they're taking snapshots of the page, it's like a full
DOM capture.
It's not just a pixelated screenshot.
You can take those snapshots and re-render them on different browser configurations.
So, you know, for example, I'm using a Mac.
I can test on Chrome and Firefox and Safari and Edge now, but I can't test IE.
You know, well, you could take that snapshot, send it up to the Apple tools cloud.
And then in there, you can test it on IE.
There you can test it on mobile platforms.
Or if you're a Windows person, like good luck with Safari.
Oh, exactly.
Right.
That's the other one.
If you're on Windows, you want to test Safari, but you can't.
Boom.
Apple tools ultra fast grid is a way to do that.
So there's a lot of really cool stuff you can do with visual testing.
That sounds fun.
Yep.
And so what I do at Apple tools, I'm a developer advocate.
So I stand between company and community.
I help the community understand good testing practices.
What is visual testing?
Help them get the most out of using Apple tools.
And also to be in the community to advocate for them.
Here are the problems.
Here are the needs.
Here's the struggles.
How can Apple tools help me?
Right.
I tell people our tool does this.
They say, we don't need that solved.
We need this other slightly different thing solved.
Yep.
And you're like, all right, I'll talk to the team.
That kind of stuff, right?
Yeah, exactly.
Yeah.
I think the DevRel developer evangelist role is super fun.
It sounds like a really neat.
If you're a little bit extroverted, you like talking to people, you love code.
Yeah.
I mean, it's great.
Yep.
So one other thing I do want to mention with the whole Apple tools, DevRel thing, Apple tools run something called test automation university, which is a free platform full of online courses about testing automation and everything on that topic.
So we got some of the best instructors in the world who have these courses.
I've taught three of the Python courses.
You know, I would recommend folks check it out.
Test automation university, TAU.
It's good stuff.
All right.
Automation Panda.
Oh my goodness.
So yes, I also happen to be called the automation Panda.
That's just me.
You know, there's no like company or anything.
It's just my moniker.
It's my Twitter handle.
It's my blog.
Or the reason I started the whole automation Panda thing back in 2016, I got my first position as a senior level engineer.
And I thought, wow, this is great.
I've achieved my career dream.
I'm senior level.
People going to listen to me now.
What's next?
Like, oh, hmm.
Up until that point, all the work I'd ever done had been behind company proprietary walls.
Even if that work had not necessarily been proprietary or secret or anything like that.
You know, I got sick of rewriting the same thing, wiki pages across multiple teams.
So I was like, you know what?
Maybe I can do something more public facing.
Maybe I can write those wiki pages on something like a blog that everyone can just Google for and find.
Especially me, because I don't want to have to repeat the same things over and over.
And so I was like, okay, I'll start a blog.
And I needed a catchy name because you go to, you know, whatever website to register your domain.
And I'm like, well, andrewknight.com is not available.
And nobody's going to remember Andrew Knight anyway.
Let me come up with something catchy.
And I just landed on Automation Panda.
Automation for test automation.
Panda, because pandas are awesome.
Yeah.
And there we go.
And pandas hate crashing web apps and desktop apps.
As I think across the different animals throughout the animal kingdom, they are very finicky about a failed app.
I suppose.
Push or whatever.
I'm just kidding.
No, that's awesome.
And I certainly know you through this.
And you've done a lot of general advocacy for testing in the Python space there.
Yeah.
I advocated for good testing before I was a developer advocate.
That is true.
Exactly.
Well, I mean, I think that that's often how people get into these roles.
You think there's probably a lot of people that are thinking, like, I would love to have that role.
So I'm going to try to apply so I can get that role.
And, you know, you did a bunch of public speaking and presentations.
And I'm sure they saw that.
Like, this guy is great.
We just need to have him on our team.
You know?
And I got hired doing in-person developer training because I was speaking at user groups and meetups and conferences and blogging.
And they're just like, I see you doing this for free.
Would you like a job to do it?
I'm like, that sounds awesome.
Let's do that.
Indeed.
So, yeah, it's definitely advice people can take sort of as a path forward.
Oh, yeah, definitely.
If they want to end up where you are, yeah.
When you generate content, that becomes your electronic business card.
That's how people get to know you.
And so if you do the things you like, the things you like will start coming to you.
Absolutely.
All right.
Now, how about we talk a little bit of testing?
Let's do it.
Yeah.
So the kind of testing that we're talking about here is somewhat related, actually, to your current job.
Yeah.
Apple tools, right?
Indeed.
I don't know if you're using the same tooling exactly or anything, but it's the similar idea of not just, okay, I've got a stack data structure and I can push a thing onto it and I can pop it off.
And if I pop two on and pop it off, it's going to be the second one.
Okay.
Our app is working, right?
It's trying to understand more of an integration black box level of testing, would you say?
Correct.
I always say there is a big difference between testing code and testing features.
Testing code is what we would think of as white box or unit testing or maybe sometimes subcutaneous testing where you're testing to make sure that the implementation of whatever code you wrote, be it a function or method or something else, is working according to specification.
Like, okay, I have a function, an absolute value function.
Let me make sure that, you know, I have a table of inputs that meet the expected table of outputs, right?
Input, rank it up.
Output doesn't match.
You know, that would be unit testing.
And so it's very good for pinpointing things quickly, right?
Unit tests are very fast.
It catches problems at their source.
But it doesn't test things like, okay, can you actually complete the workflow that this whole big application is designed to do?
That's where feature testing comes in.
That's where you have to do something black box.
Unit testing is good when you are focused in on a part of the app.
Like, this part is the part that checks whether or not I can access this page, whether or not the user's logged in.
So let me try to request it with a user that's not logged in.
Let me try to request it with a user that is.
How about now one with whose one's logged in but doesn't have access through some role thing?
Right?
Like, that is fine.
But most applications, as they grow, become like Lego pieces that click together, right?
And if you think about web apps or APIs or I don't even want to think about microservices, you know, they become these things like, well, here's the database with its schema and constraints.
And here's the data layer.
And here's my view method.
And then, oh, here, these are the routes that are set up based on this view.
And here's the static folder for the JavaScript.
And then it renders and just here's the HTML template.
Like, it'd be insanity to try to test those on a unit level and then be sure that, well, I tested the view and then I tested the template.
And somehow I feel like that's OK because they could get out of sync.
Exactly.
This portion of Talk Python to Me is brought to you by Microsoft for Startups Founders Hub.
Starting a business is hard.
By some estimates, over 90% of startups will go out of business in just their first year.
With that in mind, Microsoft for Startups set out to understand what startups need to be successful and to create a digital platform to help them overcome those challenges.
Microsoft for Startups Founders Hub was born.
Founders Hub provides all founders at any stage with free resources to solve their startup challenges.
The platform provides technology benefits, access to expert guidance and skilled resources, mentorship and networking connections, and much more.
Unlike others in the industry, Microsoft for Startups Founders Hub doesn't require startups to be investor backed or third party validated to participate.
Founders Hub is truly open to all.
So what do you get if you join them?
You speed up your development with free access to GitHub and Microsoft Cloud computing resources and the ability to unlock more credits over time.
To help your startup innovate, Founders Hub is partnering with innovative companies like OpenAI, a global leader in AI research and development, to provide exclusive benefits and discounts.
Through Microsoft for Startups Founders Hub, becoming a founder is no longer about who you know.
You'll have access to their mentorship network, giving you a pool of hundreds of mentors across a range of disciplines and areas like idea validation, fundraising, management and coaching, sales and marketing, as well as specific technical stress points.
You'll be able to book a one-on-one meeting with the mentors, many of whom are former founders themselves.
Make your idea a reality today with the critical support you'll get from Founders Hub.
To join the program, just visit talkpython.fm/founders hub, all one word, no links in your show notes.
Thank you to Microsoft for supporting the show.
Having that full application ready to go and you're testing it as if you were a user is very, very valuable.
It can be painful to set up.
It can be painful to think about all the scenarios to do, but it is also incredibly valuable in the results you get from it.
Yeah.
And I made the snarky comment about like a view or react front end as well.
Yeah.
Well, which really requires a little bit more of a test that understands the behavior rather
than just creating like a flask test app and requesting the view.
Exactly.
You're just going to get back where the binding bits of the JavaScript framework go.
Exactly.
You need something like a web browser, right?
Exactly.
Yes.
You need to pull up the page, load it in a browser and see what it does.
And, you know, you mentioned, I know this is the top Python podcast.
And so we love Python.
I love Python.
But in the web space, it's inevitable, unless you're using HTML or something.
Ha ha ha.
That Python is going to test JavaScript at some point.
Right?
Yeah.
They're going to crash together definitely in the web space for sure, unless you are purely
on the API side.
And who knows?
Probably somehow still it'll worm its way in there.
So traditionally, this kind of testing has been done by pulling up a browser.
It could be several levels.
It could be, okay, I get my feature implemented and I go click, clickety, clickety, click.
Seems like it's working.
Let's push it.
Like that's, let's call that level zero testing.
Actually, that's level like 0.1 because level zero is just make the feature change and push
it.
And then we'll see whether it crashes, right?
No test.
No test is level zero.
But then just above that is, I kind of sort of clicked around in the area that I think I
might have affected to see that it works, right?
Maybe take it from there.
Like, where do we go from there if we want to be better?
Well, I would caveat to say maybe it's not necessarily layers of getting better.
There is always a place for manual testing.
The place for manual testing is what I would consider exploratory testing because it's
still good to have a human go in there and try things and feel the experience.
Because like we said before, a lot of test automation struggles to handle things like visuals, struggles
to handle things like good design, judging design, judging user experience.
Does it feel laggy or is it responsive?
Exactly.
Performance issues and stuff.
And so people, like they start clicking and typing.
It's immediate, you know?
Like if anything is laggier than like 0.4 seconds or something, I forget the name of
that threshold.
That's categorically bad.
What we don't want to do is have the bulk of our testing coverage done that way.
We don't want to have the, let's say like the majority of our functional test cases executed
manually.
Because the idea of a test case, it's a well-defined procedure that you step through one through
and you do the steps and you make sure it works.
That kind of testing is where we might want to quote unquote level up to something like
automation, right?
Where you have these complimentary practices of you have automation do the rote, repetitive,
but still necessary checks along the way.
And then have your humans be creative in exploring and be able to judge the things that a script
can't necessarily judge for you.
Right.
That's kind of where that goes.
It would be lovely to leverage continuous integration and tools like that all over the place.
And if you don't have at least some basic level of automation, that's more or less inaccessible
to you, right?
Like, so let's take an example of, I've got a Django CMS that I built and it's open source.
And I want to allow people to send PRs to me to contribute back to this general CMS like
WordPress, but with Django press, I'll just make a random term.
It probably exists.
Who knows?
But like, imagine my Django press, I want to allow contributors and they're going to submit
stuff.
If I don't have something a little bit like the testing you're describing, then every PR,
I've got to go download it, try it out and do those things.
And as opposed to, no, the test didn't pass because you broke this thing.
First fix that, please.
Exactly.
Your automated test suites are your safety net and they should account for a very high
percentage of the coverage that you would want in your testing, right?
The idea is the automated tests will do almost all the kinds of things.
And then you would just have yourself or someone else go in and just kind of poke around real
quick, make sure everything is still good.
There's an, let me try the, okay, good, you know, and then feel good because you spent a
little bit of time, sanity check, making sure everything is still good.
Good from a user experience perspective.
While you had the battery of your automated suites batter the crap out of whatever changed
us when it, and it's like, Oh, they all passed.
Yeah.
I'm 95% sure we're okay.
Now let's go from there.
Yeah, exactly.
You can also hone in on the really important things, right?
Like in your CMS thing, maybe there's a reporting section that reports page hits over time or if
it goes down, that's not great.
But if the main page or main site won't even load, that's worse than the reporting being
screwed up.
Right.
So you can, you can focus in on those areas and really put the energy where people are going
to notice and consider it fully broken.
Basically.
Indeed.
All right.
So the tools of the trade traditionally have been Selenium for this type of thing, right?
And not to bash on Selenium anyway, it's, it's pretty awesome, but we're going to talk about
some sweet new stuff as well that also works with Python in nice ways.
Indeed.
Yeah.
So maybe tell people real quick about Selenium and then we'll talk about Playwright and you
can compare those.
Absolutely.
So as you said, Michael, Selenium has been the classic browser automation tool.
It's been around for, oh gosh, well over a decade now.
It's hard to believe.
Almost like two decades inch.
I mean, the, the early, very, very early, early things that ultimately became the Selenium
projects.
How Selenium works is that you will have your browser, whether that's Chrome.
IE, Firefox, RE, what have you.
There's the browser.
Then there is this web driver executable that acts as a proxy between the browser and your
test automation code.
And then in your test automation code, you have language bindings that will send requests
to the browser or the Selenium web driver executable.
It used to use a JSON protocol.
I think it's Selenium before they might've changed some things.
So I don't remember exactly.
Basically, you send, you send requests to the thing, its proxy goes to the browser, performs
whatever thing you wanted.
Did you want to click?
Did you want to get text?
Sends the response back through.
And so that's how your automation can control the browser.
This is back and forth between browser and your automation through this, this proxy executable.
Selenium is an open source project.
So everything is available online.
They have multiple language bindings, not just Python, Java, JavaScript, Python, C#, Ruby.
I don't know if there are any others, but those would be like the big five.
What else?
Not only is Selenium open source, but it is also open standards and open governance.
Those might be new things or new phrases for some people.
So let's go over there real quick.
Open source means that the source code for all the implementations for Selenium web driver,
as well as the other tools, Selenium ID and grid, which I'll talk about in a moment.
Those are all GitHub.
You can check out the source.
You can look at it.
You can fork it.
You can make changes.
You want to contribute to the main project.
You can submit pull requests.
And so that is all open and free.
Open standards.
What does that mean?
The way Selenium works is it uses the web driver protocol to communicate with browsers.
Web driver as a protocol is a W3C standard.
It's something that all major browser vendors are supposed to conform to.
And the reason, and that was a hard fall battle to get that to be a W3C recommendation.
What that means is that hopefully in perpetuity, web driver will work with every major browser
out there, right?
So that there's this guarantee.
We get a Zerodium instead of a Chromium in the future.
Theoretically.
Exactly.
Theoretically it'll come with that, right?
So that we could use the same protocol, meaning we could use the same tools to automate the
basic browser interactions.
So that's open standards.
Open governance means that Selenium is not controlled by any single party or private entity or single
company.
The way that the Selenium project is governed is by a consortium of open source contributors
and collaborators.
I know many of these folks, they span multiple different companies.
And so that way it's not like one person can control it.
One person can't kill it.
And again, everything is open.
So it's not like it's a secret little cabal that everybody's scheming together.
No, you can go read the meeting notes or the monthly meetings of the Selenium team.
That's Selenium in a nutshell.
Most times when people talk about Selenium for browser automation, that means Selenium web
driver.
That's like when you pip install Selenium in Python, you're getting the Selenium web driver
package.
That's the Python language bindings for the web driver protocol that you can go communicate
with the browser.
The other two projects Selenium IDE is a basically like a visual builder.
So instead of you trying to figure out your expats and everything, you can use Selenium IDE to kind of
create a visual builder for your test case steps.
And the other project they have is Selenium grid, which is this scale out solution.
So rather than running all the browsers on your local machine for testing, because that will max out your system resources very quickly.
If you parallelize, you can distribute that remotely.
So you can have like a cluster of nodes that have IE, some of them have Chrome, some have Safari.
And so then you make remote requests and do the automation that way.
So that's Selenium.
Okay.
Very cool.
And like you said, it's been around for a while.
And then the new one on the block is Playwright.
And it's conceptually people should think of it like similar to Selenium, I think is your mental model, I would guess.
But then it has some differences and advantages.
One of which is it had 10 years of experience to build upon.
True, true.
Maybe tell us about Playwright.
Sure, sure.
So Selenium and Playwright at their core, the highest level are both browser automation tools.
They go in, they do the clicks, they do the scrapes, you know, they send back the answers.
So in that sense, they're similar.
And also the main, I should also just caveat this, the main use case for both Selenium and Playwright is test automation.
You could use it for any kind of automation, but primarily people use it for testing.
Right, okay.
And I will talk mainly in the domain of testing.
I mean, you could use this to like, if you wanted to, I don't know, like refresh a page every hour and scrape it using Scrappy or something.
But anyway, let's talk, just keep the focus on testing.
I kind of would have like, in my history, would have liked to automate registering for college classes so I could get the 10 a.m. classes, not the 7.30 a.m. calculus class.
Yep, yep.
If only, if only, right?
So Playwright, Selenium, both browser automation tools.
But the ways in which they go about that are different.
Selenium uses that web driver protocol, which kind of operates outside the browser, right?
Playwright uses debug protocols.
So basically, Chrome dev tools and Firefox's equivalent and all that.
That's what Playwright focuses on.
In that case, Playwright can access things about a browser that either Selenium can't or Selenium struggles to.
It also makes Playwright run a bit faster than Selenium.
One of the big complaints about Selenium-based tests is that they are slow.
Now, this is due to the nature of them being black box that you need to have the whole system up.
The fact that...
Right.
Launch your entire browser and then we're going to send messages and then shut it down and then launch it again for the next test.
Right, right.
Like that kind of stuff, right?
So there is, based on the nature of UI or black box testing, there is sluggishness there.
But at the same time, like you just mentioned, you know, the whole browser setup thing can be kind of slow.
Playwright has some optimizations there that are pretty...
So it can be a little bit fast.
Another big difference between Playwright and Selenium, Selenium WebDriver is meant to be more of a low-level interface.
So the interactions that you would do with Selenium are very raw.
Like when you do a click, it'll send a click event and that's it.
It doesn't wait for the thing to be received.
It doesn't wait for the page to load or do anything magic.
It just goes.
And so with Selenium, you have to do a lot of explicit waiting for things.
Because if you click and you don't wait for the page to reflect and then you proceed to your next interaction, the page might not be ready.
The element might not be loaded and your test will go kaboom.
And then your test suite gets criticized for being quote-unquote flaky.
Yeah, absolutely.
Well, this is like what happens in the JavaScript world.
It's not the instant the page shows up.
It's got to then bring down the JavaScript.
Then maybe the JavaScript talks to some API and then it comes back and it binds to some stuff.
Like there's a bunch of network steps with built-in latency there.
Exactly.
That is the pain point of all types of black box testing.
There are inherent race conditions.
And when you do test automation in that type of space, then you need to handle appropriate waiting for those race conditions or else your test will be flaky.
And so in that sense, Selenium WebDriver, the tool does get a bad rap for being flaky when it's not WebDriver itself.
99% of the time, it's actually the tests written using WebDriver that don't have those explicit waits in there.
But on the other hand, like the tool gets used in the way that the tool encourages itself to be used.
And so, yeah.
Exactly.
And so that's exactly where I was going.
Because when you see some method, driver.click, you as the programmer expect it to click and kind of wait for things, right?
Like that's kind of what you think.
Nope.
No, no.
And so from experience working on many of these types of test automation projects across all languages and tools, when people are automating their tests, waiting is something that a lot of times they just don't even think of, right?
Especially when they're newer to it.
Whether that is a manual tester who's learning automation for the first time or a developer who's crossing over to automate some tests, you know?
Yeah.
Well, I mean, maybe you're just testing your local dev machine running on a local dev server where there's no network latency.
And then you go and test against your microservice deployed cloud CDN thing.
And it just doesn't behave the same, right?
Exactly.
It could have been working and working and working and working.
And now it's flaky.
Exactly.
So with that in mind, with Selenium being that low-level kind of tool, I mean, I've even talked and heard from the Selenium people on this.
Their thought is WebDriver is meant to be a low-level tool that you have to handle all those things yourself.
And they even encourage you, you have, you know, layers and frameworks on top of Selenium that will handle that kind of stuff for your needs.
In fact, at my previous company, I created an open source project in C# called Boa Constrictor, which is a .NET implementation of the screenplay pattern to handle those kinds of things.
Like in Java, you have Serenity BDD, which has a layer over it like that.
There's something called Selenide.
You know, there's tons of different little projects out there.
Sure.
Compared to Playwright.
Playwright is not a low-level interaction tool.
Playwright is meant to be more modern, more refined, more high-level, more do-things-for-you, where the framework is there to help you.
And so when it comes to waiting, most of the time that you need to do waiting in Playwright, Playwright handles it for you automatically.
So for any single interaction where you are interacting with an element, depending on that type of interaction, there is a specific kind of wait automatically built in for that element, that target element to be ready before it does anything with it.
You know, so before you go to click an element, Playwright's going to be like, whoa, whoa, whoa, let's wait about five seconds until it appears on the page.
And once that thing appears, it's a smart wait.
So boom, it'll dive in and do it then.
So you don't have that flakiness that perbades so many older test suites.
It's so good.
And when your tests are flaky, then you just, doesn't matter if it fails, whatever.
It fails sometimes.
Right?
As opposed to, oh no, the test failed.
What happened?
What went wrong?
Mm-hmm.
Exactly.
You want to have a lot of faith and trust that a broken build means something or a failed test means something.
Yes.
This portion of Talk Python to Me is brought to you by the Compiler Podcast from Red Hat.
Just like you, I'm a big fan of podcasts.
And I'm happy to share a new one from a highly respected and open source company, Compiler, an original podcast from Red Hat.
With more and more of us working from home, it's important to keep our human connection with technology.
With Compiler, you'll do just that.
The Compiler Podcast unravels industry topics, trends, and things you've always wanted to know about tech through interviews with people who know it best.
These conversations include answering big questions like, what is technical debt?
What are hiring managers actually looking for?
And do you have to know how to code to get started in open source?
I was a guest on Red Hat's previous podcast, Command Line Heroes, and Compiler follows along in that excellent and polished style we came to expect from that show.
I just listened to episode 12 of Compiler, How Should We Handle Failure?
I really valued their conversation about making space for developers to fail so that they can learn and grow without fear of making mistakes or taking down the production website.
It's a conversation we can all relate to, I'm sure.
Listen to an episode of Compiler by visiting talkpython.fm/compiler.
The link is in your podcast player's show notes.
You can listen to Compiler on Apple Podcasts, Overcast, Spotify, Pocket Cast, or anywhere you listen to your podcasts.
And yes, of course, you could subscribe by just searching for it in your podcast player,
but do so by following talkpython.fm/compiler so that they know that you came from Talk Python to me.
My thanks to the Compiler Podcast for keeping this podcast going strong.
Before we dive in too much to Playwright, just a couple of questions that I think there that are interesting and worth covering.
Dave Sharp says, I use Selenium for some headless browser tests and automations.
Is that possible with Playwright?
Yes.
Yeah.
So real similar, I think the API is probably a little cleaner as well, as we'll see in a minute.
Then Micah also says, absolutely can recommend Playwright.
And the robot framework side browser library is built on Playwright and Selenium library on top of Selenium.
Faster and just makes sense.
Boom.
Very cool.
All right.
Well, we've talked about some of these differences and stuff.
Let's maybe just highlight some of the, you've introduced it pretty well across browser because it does Chromium WebKit and Firefox.
And when you say Chromium these days, you're like 96% of all the browsers, sadly.
That covers a lot, right?
That's not just testing for Chrome, but that's testing for Edge, Brave, Vivaldi, et cetera, et cetera, cross-platform.
I want to go back to browser because there is an interesting difference here to note between Selenium and Playwright.
When you use Selenium, you're testing the full browsers, right?
You're testing Google Chrome.
You're testing Mozilla Firefox, Microsoft Edge.
Does it even load up like extensions and stuff like that?
Or is it just, is it more bare?
Is it like maybe just below your customizations?
In Selenium, it's the full browser, whatever you've got.
You can do things from a command line to kind of like play with certain things like what user profile use, what user data directory and all that.
But essentially, the browser that's installed on your machine is what Selenium WebDriver would use.
But in Playwright, it doesn't use those quote unquote stock browsers.
Playwright uses browser projects.
So with Playwright, you are not testing Google Chrome.
You are literally testing the Chromium project.
You're not testing Mozilla Firefox.
You're testing the open source Firefox project.
You're not testing Apple Safari.
You're testing the WebKit project.
And so when you go to set up and install Playwright, part of the Playwright install command is it will download the latest versions of these browser projects and install them on your machine.
And so when Playwright runs, it's running against those.
In a sense, it's a more pure stripped down, just the essence of the rendering engine, JavaScript.
Exactly.
VM and stuff.
Exactly.
So it is.
That's really nice.
It's an opinionated take.
You seem to have a very positive view of that, Michael.
I do.
Yes.
I think it's cool.
I think it's awesome.
I think it's lighter weight.
But I would also caveat they may not be usable in all contexts.
Like if you are a government contractor or you're working at some big bank or some of these older, more legacy shops, they may have very strict requirements on browsers and versions to test.
It's out there.
It exists.
Maybe you want IE 11 and you've got to just run that because they're they're crummy SharePoint installation from 10 years ago.
Stuff like that.
Unwilling to upgrade like anything but that log into it or some weird thing like that.
Right.
Exactly.
So anything like that may be a showstopper for folks who want to use Playwright.
My gut tells me that's a very, very small sliver of the wider industry, but it is something to call it.
So kind of modern web browsers is where you're going to end up.
Yes, exactly.
Exactly.
Sure.
Okay.
Across platform, Windows, Linux, Mac plus CI and headless.
That was sort of touched upon in Dave's question, but maybe discuss this headless versus headed idea of this, these types of frameworks.
Sure, sure.
So when you're the human and you open up your browser, that's headed mode.
Why is it called headed mode?
Because it's rendering in front of you and it's doing all that fun stuff and you can see it visibly on the screen or in whatever viewports you've got.
Headless mode is a way that you can run browsers without having it pop up on the screen and render all that stuff.
It'll still do the rendering.
It just won't graphically display that to you.
When you run automated tests, specifically like in a continuous integration environment, maybe in a GitHub action or something, you want to run headless mode.
Why?
Because it uses fewer resources.
It's a little bit faster.
Nobody is there to look at the screen when it pops up.
It's got a button.
Would you like to upgrade?
Yeah.
Chrome is great, but you should try Edge.
It has these new shopping.
No, I don't want that.
Go on.
Yeah.
Thanks.
I know that wouldn't happen in the project.
That might be more of a Selenium thing if you get like these weird, typically, you know, periodic pop ups, right?
From the browser vendors.
Indeed.
When headless modes first became popular, I want to say about like five years ago, like it really became popular with PhantomJS.
And then Chrome basically came along, did the same thing and killed the PhantomJS project.
The dude just like, I'm done.
Use Chrome instead.
Like TLDR on the GitHub repo.
I was like, wow.
Now all the browsers do this.
But it is a recommended practice that when you're running tests for credit, like in CI or something, you do headless mode.
Also, if you try to do headed mode in certain CI tools or GitHub actions, sometimes you might get these walkie errors like, you couldn't render this thing.
Yeah.
Or maybe like the desktop UI tools or frameworks are not set up to actually show windows or some weird thing.
But headed, you might want to see what happened.
Like if something goes wrong.
So you would use headed mode when you are developing the test automation on your workbench.
Like, you know, I've got Visual Studio Code open and I just code my test.
I want to run it real quick.
I want to see it pop up and dance through the page.
Right.
That's when I would use headed mode.
Also, interesting thing.
I believe by default, Playwright uses headless mode.
It's not something that you have to.
Yes.
I think you're right about that as well.
Yeah.
If you want a headed mode, you got a headless equals false or headed equals, I don't know.
We'll see it in a second.
We'll get to the examples.
But you got to opt in.
And then you already mentioned the Playwright API is TypeScript, JavaScript, Python, .NET, and Java.
And people are like, ah, I'm not using it.
It's not Python.
Well, the browsers aren't Python anyway.
So it's just like one more layer of who knows how many technologies are in there.
But like NumPy has a C layer.
This is like a layer to talk to the thing that does the work.
And it's a pretty nice API, as we're going to see in a moment.
And then you can also test mobile web, even if you don't have a mobile web thing, because it has native mobile emulation.
Yeah.
Correct.
That's all, you know, viewport size, some of the little options on whatever request it has, just to kind of somewhat emulate what a mobile browser would look like.
Yeah.
Very cool.
Test like responsiveness and like a bootstrap menu or something.
Auto-wait.
That sounds very promising.
It waits for elements to be actionable prior to trying to click them.
You already went into the flakiness and race conditions of all that, but that's pretty cool.
Web-first assertions.
What does that mean?
So that sounds good.
Yeah.
Because you're testing the web.
So that kind of goes hand in hand with auto-wait.
For those of you who are familiar with unit testing in Python, whether that's with unit test or pytest.
No, unit test has its like assert that library.
pytest, you literally just use the assert command in Python, right?
Assert this, assert that, all that kind of stuff.
When it comes to web testing or really any sort of black box testing, the basic kind of assert statements can be limited.
Again, because a lot of times you have to wait for the value to be ready before you can make a Boolean condition of an assertion on it.
That's basically what these web-first assertions mean.
In Playwright, there is an expect function.
It's in JavaScript.
It's in Python.
I think it's in the others.
But basically, you would say something like expect a certain locator to have a certain text value.
And what it'll do is it'll wait until said phrase has that text value or wait until this locator appears on the screen.
It's a more fluid kind of way of writing assertions.
And it also has that built-in waiting.
And they call it web-first because it's the idea that it's putting the emphasis of the condition on the web elements as we would naturally understand them.
Not trying to shoehorn them into some fixed static Boolean condition.
Yeah, that's very cool.
Okay, and then the last selling point on resiliency here is tracing, configure tests, retry strategies, capture execution traces, videos, and screenshots.
So, yeah, we'll see some of the tooling, the GUI tools and stuff for this.
But, yeah, this sounds really nice.
Mm-hmm.
If your test fails in CI and you get a video, they click there and then that gave a, you know, 400 or something.
In JavaScript instead of filling up this form, like, that sounds pretty nice.
Oh, yeah.
So, yeah, and that's a huge advantage that Playwright has over Selenium as well.
Like, in Selenium, you can capture screenshots along the way, but there's no built-in video capture.
In Playwright, you can not only get screenshots if you want explicitly through the code, implicitly you slap on the screenshot command line argument after every single failed test, it'll poop out a screenshot.
Or you can just be like, give me the whole dang video so I can trace through a watch.
I mean, screenshots are great.
Video is lit.
It's incredible.
It's like, oh, my gosh, they did it.
They planted the flag.
Victory.
This is amazing.
Yeah, because it's one thing to see it where you have it in headed mode and you can interact.
It's another when it's on a remote system, maybe a different platform, and you're like, what went wrong with this thing?
Exactly.
Because, like, that's the thing.
Like, in olden times, I kid you not, when people did automation, they would literally push the button on the machine and just, like, watch it go.
Wait for it to finish.
And that was automation.
No, no, no, no.
Like, true automation is it's in some sort of CI system.
You know, it runs on a, after every pull request, after every commit, or maybe if the test suite is too big, it runs nightly or, you know, a couple times a week.
You are not there to watch it fail, right?
So you need all the evidence you can get.
What's the best evidence?
Video.
Video to see what's happening, and then you dig into logs.
Yeah, I mean, your only visibility is spinning, spinning on CI and then failed.
Exactly.
And so, yeah, it's really good.
I love it.
Okay.
Stuff about running on modern platforms, but then let's talk the isolation.
I think that that's huge.
There's two things about sort of authentication and cookies and stuff like that.
It's pretty interesting.
But then just also the isolation, right?
You have this very much in testing, right?
Yes.
You don't want to depend on the order of tests, for example, at a unit test.
And this, you kind of like don't want to depend upon the last page you visited for browser tests.
And specifically with the isolation and Playwright and the browser context here.
You had mentioned earlier, Michael, about in Selenium, how for every single test, you would have to open a new browser, open a new web driver process, and at the end of it, close it, close it.
And the reason you do that, you open and close for every single test is because you want that isolation, right?
You don't want to share web browsers across tests because things can go wrong.
With Playwright, one of the optimizations is for the entirety of your test suite, you do only have one browser process.
So you only have one Chromium process.
It's at the beginning of everything you started up and it exists throughout all tests and you close it.
You're like, well, how, wait, doesn't that violate independence and isolation?
What Playwright does is it creates what's called browser contexts out of that.
So the slow part is...
It's like a new private incognito window sort of, right?
Yes, exactly.
It's basically like your own session, your own window, your own user account kind of thing.
Browser contexts are very quick to create and close.
So you don't have the like five second to 10 second startup and teardown time per test.
It's like a split second.
So that makes you be able to set up your test a lot faster.
And it's basically, it's like an incognito session.
So you have access to everything in your scope.
But if there are other contexts running at the same time, e.g. you're running parallel tests,
you can't access anything in the other sandboxes.
So it's safe.
And it's really a game changer for browser-based testing.
And as you mentioned, just like I have a quick count, I think I have six browser tabs
and a progressive web app open right now.
They don't interact, right?
I mean, that's just how browsers are built.
That if I visit playwright.dev and then some other...
Selenium, whatever, they don't get to spy on each other, right?
That's just how it works.
And so it leverages that to say, well, we can do more than one tab at once.
Let's go.
And all of your authentication or browser context, you know, any of the cookies you have protected by browser context.
So you can do a lot of really cool stuff.
It's not just you're on a different tab because that comes down to pages off of browser context, which is another thing.
But it's full context of what's going on.
Yeah.
Very cool.
And then the last sort of selling point that Playwright talks about is that they have a bunch of tooling to go along and help you, right?
We're going to talk about the API next and go see that.
And the API is really nice.
But sometimes you're like, oh, what is that CSS selector?
And I've been writing CSS selectors for many years, so it doesn't bother me.
But I remember the beginning of like, what does it mean when there's the arrow versus not the arrow?
Or does it need the space or not the space between the dot and the preceding element?
You're just like, oh, I'd rather just go hit me with a stick.
I've done more content.
I just can't take this anymore.
I'm pulling my hair out.
So there's some tools like a code gen, sort of record my interactions and then generate Python or other language, I guess.
For me, that'll help a lot there, right?
Yep.
Maybe we could talk a bit about really high level.
Then we could like, we'll dive in.
We'll pull some pictures about it.
Sure, sure.
Yeah.
I mean, it's basically that like it fires up a browser.
You click through.
You say, I'm done.
And then poops out all the stuff you did in Playwright code.
Yeah.
Well, you talked about it using the dev tools.
It's very much like the inspect element of the dev tools.
Yep.
Okay.
And then there's an inspector, a similar, but also kind of like lets you step through and a trace viewer as well.
That's a little bit like the network tab, I guess, plus snapshots.
Yeah, yeah.
Screenshots.
So trace viewer is something that you would kind of put on a test for monitoring and then it poops out all the logs and stuff.
So you can kind of better trace through it after the test is done.
Live DOM snapshots and all that good stuff.
Okay, cool.
Let's maybe talk through some of the code and how it works.
Install.
Easy.
Know it.
Love it.
Pip install it.
But it looks like there's two steps.
I pip install Playwright and then I playwright install.
Ah, yes, yes.
So pip install Playwright is what's going to give you the Python Playwright package.
I know that's a lot of P's.
What Playwright install does is it installs those browser projects, Chromium, Firefox, and WebKit.
Right, okay.
You can also, I think you can do Playwright install Chromium if you want just one, right?
Correct.
You can focus in.
Yep.
You can pick the one to install.
Yeah, but it's 2022.
Just install them all.
Let it have it.
Yep.
One other thing that if you're in Python, I would strongly recommend you include would
be a pip install Playwright pytest, which is the pytest plugin for Playwright.
Again, plop, plop, plop, plop.
The Playwright package alone is going to be the browser automation tool.
The pytest plugin for Playwright is what gives you all the tie-ins to pytest so you can make
really nice tests.
It gives you the command line options like the headed option or the video option.
It gives you the fixtures for getting the context and the page.
So if you're going to be using it for testing, definitely Python, Playwright, plus pytest.
Amazing combo.
Cool.
If you're just doing pure automation, maybe you don't need the pytest plugins and so on.
Yeah, cool.
Okay.
So we've installed it.
And then immediately what might catch your eye is when I import, I import Playwright.either
sync API or async API.
And you're like, oh, wait, there's two APIs.
How lovely.
But maybe talk us through what the code, keep in mind this audio, but give us a sense of
what does it feel like to write code for the sync API?
And then we can see how it changes with async.
Sure, sure.
So with the sync API, of course, everything is step by step.
It waits before it goes on to the next thing.
I would say if you're doing test automation in Python, the sync API is the way to go.
And in fact, that pytest fixture I mentioned gives you everything sync.
You would use async if you're doing more just rogue automation.
You know, you're trying to sign up for your college courses.
That would be what you would use the async.
So in this little snippet, what it's doing here is with sync API, you're saying browser
equals p chromium launch.
That's opening up a chromium browser instance for Playwright.
So that's the full browser.
That's the start of the browser process.
Then off of that, the next line, page equals browser.newpage.
What it's saying there is from that browser instance, create a under the hood.
This is not included here, but create a new browser context.
And from that browser context, create a new page and give me the page options.
All of the interactions in Playwright are going to be going off of that page.
If you want to click, if you want to scrape, if you want to send text, all that is going to be on the page.
So following that, the next line is the first call we see page.go to, you know, some web address,
http colon slash /playwright.dev.
So that would be an example of a browser interaction on the page.
That one, because that will load the webpage, it's directly off the page.
A lot of times you might need to say page.locator with your CSS selector, expat ID to identify an element on the page
and then do something on the element.
So you would say page.locator, blah, blah, blah, dot click.
Page.locator.fill with certain text.
That would be like typing text.
Right, okay.
Then the next line we see here.
Nice, then you can access like properties like page.title, right?
Oh yeah, you can get page title, you can get page URL.
I don't know the exact names of everything, but if you're using like Visual Studio Code
and Python typing, then you can get on a complete and find the whole list.
Beautiful.
Yeah, yeah, that's awesome.
So another thing it seems like I could do here is we've got p.chromium, p.webkit, I presume, and so on.
I could use a parameterized pytest test and give it the browser for Chromium.
Okay, so.
No?
So, okay.
How do I just test all the browsers?
Two things here.
First of all, what you just recommended is an antipatter.
You never want to use pytest parameters to choose browser.
Browser is a browser choice.
Browser choice is a test control input.
That's something that you want the user to specify, I want to target this browser.
And the way you would want to treat that is to say, okay, I have my whole test suite.
Honestly, all web UI tests should be able to run against any browser.
There's no reason one would test on Chromium versus Firefox or something.
So, you would want to say, hey, for this entire test run of these tests that I'm filtering on my suite, target Chromium.
If you wanted to test on Firefox, you spin up another process and say, okay, run these and target Firefox.
Test control input passed in and handle.
Now you're probably thinking, oh, okay, so now I can use a pytest fixture to read an environment variable and pass it in that way.
That's what the Playwright pytest plugin does for you.
Okay, nice.
Yeah, we'll get to that in a second.
Yeah, yeah.
That's another reason to use the plugin is because literally it's a command line option.
You know, project Chromium, project Firefox.
Or you can specify all of them and run three at a time.
Got it.
Okay, cool.
And then there's a similar async API, but instead of using a with block to create the browser's sort of session up here, right?
Instead of with sync playwright SP, we have, we create an async with block to create an async playwright.
And then we await launching the browser or launching the process and then await getting the page.
And there's a lot of await on this page, honestly.
This might be the most await dense async thing I've ever seen in my life.
Oh, you should see the JavaScript code.
Which is not necessarily negative, but this is all await.
Like six lines of await.
Yeah, no, you're absolutely right.
In fact, right before our chat today, I was doing playwright in TypeScript.
And yeah, it's await, await, await, await, await, all the way down.
At least in Python, you get to choose.
Yeah, true.
Yeah, JavaScript doesn't have the sync options.
Yeah, so, but otherwise it's the same, right?
Exactly.
So when would I use, like when would, let me rephrase this.
When would you use the async API?
I would use the async API if I'm trying to do some sort of browser automation apart from test automation.
Like if I'm trying to write a tool that's trying to log in and register for college course,
or I'm trying to scrape numbers off of a dashboard on a website that change every five minutes or something.
That would be the case where I would probably write like a pyscript and just puke everything in one file.
And I would use the async API.
I would use sync API for test automation.
Got it.
Okay.
Would it make sense to use the async API if I was trying to run on all three browsers at once?
I mean, yeah.
Why would it still not go async there?
Well.
Maybe like an xdist or something like that on my PY test?
That would not be the appropriate way to handle that.
What you would do is you would code your test and it would be generic enough to run on any browser.
And then when you would launch it using the PY test plugin, you would specify all three browsers to run at the same time, which would basically triple the test.
And then you would use PY test xdist dash three.
So it would parallelize that.
Right.
So you would write the test as if it's generic and then you would use control options to parallelize and cross browser tests.
Yeah.
Probably the xdist anyway.
I don't know.
You probably know.
It's probably multi-process, not threaded anyway, right?
Yes.
Yeah.
So it doesn't really matter if it's asynchronous.
Correct.
Okay.
Got it.
And then here's the example of like how you might launch it in headed or not headed mode.
You would say like Firefox dot launch headless equals false.
There's another interesting parameter here.
Slow mo.
Mm-hmm.
Like don't you want your test to be fast?
You went on and on about how it was good.
So when you are developing tests on your local workbench, and like I said before, that's when you want to do headed because you want to see it.
Playwright is so fast that sometimes you can't track what's going on.
I kid you not.
It's fast.
And so what you would want to do during like your local development or debugging, you might want to inject a slowdown after every interaction.
Usually I use like 1,000 or 2,000 milliseconds just to kind of.
Yeah.
Also, I would recommend just like with headless option, slow-mo option, you can use the command line.
And I would even say that's the preferred way rather than injecting directly to code.
Yeah.
Probably also just to be nice.
If you're not testing, but you're going around scraping on people's websites, don't hit it as fast as the network will allow you.
Yeah, because some websites will identify you as a bot and be like, nope, I'm rejecting your request.
So if you inject a slow-mo, you seem more like a human.
You'll skirt under the radar.
Ooh, I didn't even think of that, but that's right.
Yeah.
I'm sure that that actually, it may not be the intent.
The intent is to make it human interactable, but it's still, it might be necessary.
Get in that college course, get that 10 a.m. class, don't get banned.
Okay.
I actually did do something like that when I was in college, but using a dial-up modem because I had to talk to somebody.
But it was glorious.
I had the best class schedule of the year that year.
Nice.
Okay, so another thing you could do is you can record scripts using Playwright, CodeGen, and then give it a URL.
And then it'll watch you interact with it and then generate Python, try to mimic those interactions, right?
Mm-hmm.
Okay, that's pretty awesome.
We talked a lot about, we'll come back to the pytest in a second.
There's also a REPL mode, which is pretty, I mean, I guess that's just saying like you can call Python code in a REPL.
That's not super interesting.
If you're coming to Python from another ecosystem, this might be a big deal for you.
I think for us, we're like, oh yeah, you can do any Python in a REPL.
No, it's simple, whatever.
So somebody come from like the Java world, oh my gosh, this will blow their mind, you know, probably.
Yeah, that's for sure.
I guess I'd never really thought about creating an async REPL, but you can create an async REPL using Python-M asyncio and then you get a REPL, but it lets you write await.
I've never done that.
So I guess I learned something.
Then also it has this interesting way to build itself into a standalone executable.
So you don't need Python or anything else to run it using PyInstaller, but there's some integrated commands.
Tell us about this.
Like I'm searching for a way in which this might be relevant to me.
Well, that would be like the tool that we mentioned versus a test automation suite, right?
If you wanted to build your college course hacker scheduler thing, you could build it.
I see.
And then.
Yep.
You could build into it an executable and then it's a little easier to run.
That's all.
I see.
Then you tell it, it takes these command line arguments and then it goes and it.
Yep.
Okay.
Got it.
If I want to share it.
Sure.
By the way, the instructions on the website, people are watching.
There's a bash, a PowerShell and a batch version.
The bash version like doesn't have backslash ends or something.
I don't know.
It's a little weird.
Just look at the other ones.
So realize that's three lines.
Oops.
All right.
It does have some interesting ideas.
You talked about the waiting and it says, don't use time.sleep.
You might be able to get away with async.io.sleep, but don't use time.sleep.
Use page.wait for timeout instead, which is interesting.
Apparently the time.sleep messes with its internal asynchronous.
Interesting.
Or something.
So yeah, just people be aware of that.
All right.
Let's talk pytest plugin real quick.
Sure.
So we could write a pytest test that takes a page object, which is.
The browser process is launched.
A session is created and a page has been created and then it's handed to you.
Exactly.
So like that opening code snippet we just talked about, you don't need to do that when you're
doing pytest with the plugin.
You basically say, I want to use a page.
Fixture go.
Boom.
And it gives it to you.
So you can immediately jump into things like page go to, page locator, give me this, page
title, page click, you know, straight from the test function, which is really, really
nice.
It cuts down on all that boilerplate.
Yeah.
That's, that's very neat.
And then here, right below that in the, it shows the CLI options, pytest --headed,
--browser, Firefox or multiple browsers and so on.
Mm-hmm.
Yeah.
Very nice.
What else should we talk about?
Maybe we could talk like text input and stuff just really quick, because I feel like that
goes a little bit beyond just CSS selectors, like the clicks and the inputs and the.
Sure, sure, sure.
So on.
So which one do we talk about?
Inputs, locators?
There should be a section on selectors if you go down, which I would recommend.
There you go.
So the selectors are the starting point of finding things on the page.
You can identify elements on the page from many different kinds of selectors.
You can have an ID, boom, you nail it, you know, assuming it's your unique on the page,
right?
You can use a CSS selector.
You can use an XPath.
All those are things that are also selectors available with Selenium WebDriver and Cypress.
But Playwright has a few other kinds of selectors that it supports.
One of the most helpful ones is what they call a text selector.
Oh, you've got it on the screen here.
Yeah, there you go.
So like I want the button that says login.
Correct.
Exactly.
Because I don't care what kind of element it is.
I just want the element that has a text that says login, that has submit.
As long as it's the only one on the page, you're going to get a right.
That lends to the developer experience, right?
Because you're trying to figure out CSS selectors and XPaths.
There's a cognitive load.
Sometimes you have to do it.
But if you don't have to and you can do something easier, it's better for you and for the test
case.
Simple is better than complex.
And so here, right, yeah.
Give me the text.
Boom, I'll find the element.
So that's one of the really, really cool selectors.
Yeah, that's fantastic.
And then you can come in here for input and like go and say, I would like to check the check
box that has the ID agree.
Or that has the text XL.
Like what size of t-shirt do you want?
I want XL.
Check that.
That radio button or that check box.
That's super cool.
Actually, I should comment that the commands we're seeing here are things like page check,
page uncheck, page fill.
That's actually no longer the recommended practice with Playwright.
You can do it this way.
What do they suggest?
What they suggest is page.locator, pop in your selector, and then dot whatever the interaction
is.
So in these cases, instead of page dot check, agree will be page locator agree dot check.
And the reason they recommend that, even though it's more verbose, it's ultimately supposed
to lead you to a refactoring into things like page objects, right?
Because you are separating the concern of page structure from interaction.
Whereas when they're together, even though it's more concise, it is readable.
You're combining those concerns.
It doesn't really matter.
You can use both ways.
Sure.
Okay.
Yeah.
These are nice.
All right.
So really, basically the takeaway, like for example, here I can go and find me the button
that says text submit, and then I can do a hover over it and then click, which I think
is interesting because often it doesn't matter.
But sometimes if you hover over a thing, it exposes different DOM elements that when you
click on them may have a different behavior.
Indeed.
So you have this really fine grain control.
Indeed.
Got a few.
Go.
No.
Okay.
Finish your thought.
Sorry.
I was going to say like, also in that example, we just showed you created the locator object
to one time, and then you perform multiple interactions on it.
Whereas if we, if you had repeated or if you had combined the calls, you would have under
the hood duplicated the creation of the same locator object.
So there's a sense of reusability there as well.
That's all.
Got it.
All right.
Let's round out our conversation here just quickly with the tools.
So I think that these are really nice.
These visual tools here.
All right.
The first one I pulled up first is the playwright inspector, and it's kind of like, I don't
even know how to describe it.
So it's, it's as if you went through and you did a bunch of CSS stuff and then playwright
wrote asynchronous Python code with the things like page.click and whatnot that we discussed.
And then, then you can go and check it out.
So this is kind of like a playback understanding type thing, right?
Yeah.
How would you characterize this?
So this is like saying, okay, this is what your code did.
Here's more information on it.
Very similar to Chrome dev tools.
I will caveat to say, I have not used this much myself.
This is also kind of new to me too.
Also on top of that, I should say the playwright team keeps pumping out new, awesome stuff all
the time.
So hold on to your butts.
They just keep making more awesome, cool stuff.
Yeah.
Apparently it has features for like debugging selectors for stepping through like one of
these playback scripts to see how it goes and so on.
It's really cool.
Real time stuff here.
Yeah.
This is super neat.
Okay.
Another one, the trace viewer.
This, like I said, looks a little bit, it's a little bit like the dev tools of a browser.
If you open up the network tab and then select, show me the response in that view for people
who are not seeing this, but you can go to the playwright.dev site and check it out.
That's a good way to describe it.
And it bundles up like so many things.
Like I think you can say like, oh, I want to capture the screenshots.
I want to capture the video.
I want to capture the DOMS of the pages.
I want the stores.
Like it all ended up like, I think it bundles it up all for you in one artifact.
It's like, you're just tested done.
Here you go.
Have fun looking at it.
So it's the kind of thing where you could, when you, let's say you're running this in continuous
integration, you know, test fail, it bundles all this stuff up, saves it for you as an artifact
and then you can go look at it later for the ones that fail and be like, oh, so here's
all the context of what went wrong.
And you can really get in there and figure out what happened.
It's fantastic.
It has all the actions.
You click on them and it says, what was the action?
What was it like before?
What was it like after?
What did the network do?
Yeah.
Really good.
And then test generation because, hey, we don't need to write tests.
We'll just tell it to go.
No, I'm just kidding.
Tell us about this.
This is pretty cool though.
This is like fire up the browser.
Let me interact with it and then generate a script that I can go from there.
Yeah.
Basically it's like a screen recorder.
Yeah.
You start the recorder, you navigate through the webpage, you know, you do your workflow,
you stop the recorder and then it turns all of the things that you did into a Playbride.
Right.
Instead of recording video, it records asynchronous Python.
Basically.
So that it generates.
Now this is really cool and it's super easy.
The other thing that's worth noting here is they talk about authenticated state.
So if you've got to log in and set up some cookies and local storage, you know, like even if you've
got a JavaScript app that needs to read and write stuff to local storage, you can sort
of save and load that from a JavaScript, the JSON file rather.
Yeah.
So because that's another thing, particularly with test automation, how many times you have
to log into your app under test, username, password, token or whatever.
And so, I mean, you can do this with pretty much any browser automation tool.
This is how Playbride does it.
You're basically caching that authentication so that you can reuse it for different sessions
or tests.
So you don't have to burn that five seconds of log in every single time.
Sure.
If you're not trying to test the log in flow, it's just in your way.
Correct.
Yeah.
Fantastic.
I guess debugging tools.
We could look real quick.
I mean, I feel like we kind of touched a lot of them.
Anything else you want to highlight?
Maybe running in debug mode?
I mean, it's all goodness.
I would say go read the docs up on it.
There's more than we can cover in a one hour discussion.
Yeah.
Well, I think we're down to minutes, not hours.
So maybe leave it there.
There's a bunch of guides about like auto-weighting, testing APIs, browser context, JavaScript events.
Like there's a lot of stuff to go in here.
And I'll check out even testing video.
We're recording videos.
Yeah.
Cool.
Fantastic.
And for folks who want to learn more about Playwright, what I can recommend is that I have done a tutorial on Playwright in Python.
It's on my GitHub account.
It's playwright-python-tutorial.
I have given this at PyCon.
I gave this at Python Web Conference.
I think I gave this at the TAU Homecoming last year.
And in this repository, what it has, it has not only example code, but it has full instructions on how you build a test automation project with these tools.
And it walks you through in glorious detail all the way.
If this is something you want to get hands-on with, yep, there it is.
Boom.
Give that a try.
Check it out.
Follow the instructions in the tutorial folder.
And let me know if you get stuck.
Yeah, this is really great.
People can follow along and play with it, right?
Do a little DuckDuckGo.
Basically.
Yeah.
No, but take some other public website like DuckDuckGo and figure out how you might go about testing it, right?
Work your way through understanding what you should do to test it and then put that into action with Playwright.
Yep.
All right.
Well, I think that pretty much is the time we've had to talk about this.
Anything else you want to quickly touch on before we call it a wrap?
No.
I mean, have fun with it.
I think Playwright is awesome.
I really love what the team is doing.
And if you ever have, if anyone ever has questions, all testing, automation, Playwright, Selenium, you name it, hit me up on Twitter, AutomationPanda.
Right on.
All right.
Now, before we get out of here, I've got to ask the final two questions.
If you're going to write some Python code, what editor do you use?
Your tutorial may have given it away if people have seen that, but go ahead.
VS Code.
That's what I've been using recently.
All right.
Right on.
And then notable PyPI package.
I mean, pip install Playwrights, one of them.
But something else you want to recommend, you're like, oh, this is cool.
People should know about X.
I mean, typically I would say pytest, right?
But in fact, I just released a package on PyPI during PyCon.
I got it done before the final closing keynote.
Oh, nice.
Okay.
It's called Screenplay.
It is a Pythonic implementation of the Screenplay pattern.
It's very minimal right now.
It doesn't even have documentation.
But if anybody knows about Screenplay Pattern and wants to help contribute to that, check out Screenplay.
Hold on.
There it is.
This one?
Yeah.
All right.
I'll put that in.
Put that in the show notes.
Yeah.
Very cool.
Thank you.
All right.
Yeah, you bet.
Well, it's been really great to have you here.
Thanks for sharing all your experience with Playwright.
It looks very exciting.
It looks like something you just want to play with.
Yeah, indeed.
Well, thank you for inviting me to talk.
I'd love to do it.
Yeah, you bet.
So people are excited to get started.
Final call to action.
What do you tell them?
People are excited to get started with Playwright.
Check out the website, playwright.dev.
Check out my tutorial with the link.
And also, if you ever get stuck, you can reach out to me or join the Playwright Slack.
The folks in there are very helpful and very quick to respond.
All right.
Fantastic.
Well, thanks again for being here.
It's great to chat with you.
Thanks, man.
Appreciate it.
Yeah.
You bet.
Bye.
This has been another episode of Talk Python to Me.
Thank you to our sponsors.
Be sure to check out what they're offering.
It really helps support the show.
Starting a business is hard.
Microsoft for Startups, Founders Hub, provides all founders at any stage with free resources
and connections to solve startup challenges.
Apply for free today at talkpython.fm/founders hub.
Listen to an episode of Compiler, an original podcast from Red Hat.
Compiler unravels industry topics, trends, and things you've always wanted to know about
tech through interviews with the people who know it best.
Subscribe today by following talkpython.fm/compiler.
Want to level up your Python?
We have one of the largest catalogs of Python video courses over at Talk Python.
Our content ranges from true beginners to deeply advanced topics like memory and async.
And best of all, there's not a subscription in sight.
Check it out for yourself at training.talkpython.fm.
Be sure to subscribe to the show.
Open your favorite podcast app and search for Python.
We should be right at the top.
You can also find the iTunes feed at /itunes, the Google Play feed at /play,
and the direct RSS feed at /rss on talkpython.fm.
We're live streaming most of our recordings these days.
If you want to be part of the show and have your comments featured on the air,
be sure to subscribe to our YouTube channel at talkpython.fm/youtube.
This is your host, Michael Kennedy.
Thanks so much for listening.
I really appreciate it.
Now get out there and write some Python code.
Thank you.