Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Add Gradle examples to documentation #571

Closed
jhyot opened this issue Aug 18, 2021 · 28 comments · Fixed by microsoft/playwright#26418
Closed

[Feature]: Add Gradle examples to documentation #571

jhyot opened this issue Aug 18, 2021 · 28 comments · Fixed by microsoft/playwright#26418
Labels
documentation Improvements or additions to documentation good first issue Good for newcomers

Comments

@jhyot
Copy link

jhyot commented Aug 18, 2021

Feature request

Is it possible to add Gradle examples to the Playwright documentation along the current Maven ones?

@yury-s
Copy link
Member

yury-s commented Aug 18, 2021

It'd be nice to have one! If anyone who uses Gradle is willing to contribute such an example we'd appreciate that.

@jhyot
Copy link
Author

jhyot commented Aug 18, 2021

I am using gradle so I could try to reproduce all the examples, and then contribute them.

@jhyot
Copy link
Author

jhyot commented Aug 19, 2021

It turns out that Gradle doesn't have a direct equivalent of Maven's exec:java goal. So the CLI commands cannot be translated 1:1 into Gradle. Instead, a new task or multiple tasks have to be defined in the project's build.gradle which then can be executed.

Because that requires a bit more description instead of just a "run this line" instruction, how would you like to integrate the gradle instructions into the doc?

Example of a task that needs to be added to build.gradle:

task runPlaywrightCli(type: JavaExec) {
  mainClass = 'com.microsoft.playwright.CLI'
  classpath sourceSets.main.runtimeClasspath
  args 'open'
}

Which can then be run with ./gradlew runPlaywrightCli

Also, gradle files can be written in Groovy (the original way) or in Kotlin (newer way which is pretty popular for new projects I think). How do you want to deal with this? I have only a Groovy setup, so couldn't easily test the Kotlin code.

@jhyot
Copy link
Author

jhyot commented Aug 19, 2021

args above can also be set dynamically from the CLI, so the minimum would be to define one "generic" Playwright task, and then I think all the Maven examples can be translated into Gradle commands that run this task with a set of arguments.

@yury-s
Copy link
Member

yury-s commented Aug 19, 2021

I thought you were originally talking about just gradle config for adding playwright deps but now I see that you are talking about all the cli examples. In that case I believe we'll need something like TypeScript/JavaScript tabs (see e.g. this page) but for the two build systems Maven/Gradle. As for the task definition I'd like the command line to be as close as possible to the node.js one. For example if it's

npx playwright open --device="iPhone 11" wikipedia.org

in nodejs it'd be nice to map it to something as concise as

./gradlew playwright open --device="iPhone 11" wikipedia.org

in a Gradle project. Would that be possible? As for the syntax preference we could provide the snippet in both Groovy and Kotlin similar to how Gradle docs do it. If not, I'd stay with more conservative option of Groovy as I'd expect clients that write their scripts in Kotlin to know how to translate Groovy to Kotlin.

You probably know this already but just in case, our docs live in the upstream repo and then we roll it periodically to playwright.dev to update it so these changes would need to go the playwright repo.

@andydelso
Copy link

Also, gradle files can be written in Groovy (the original way) or in Kotlin (newer way which is pretty popular for new projects I think). How do you want to deal with this? I have only a Groovy setup, so couldn't easily test the Kotlin code.

There are some neat setups on Gradle website that toggle between Groovy and Kotlin formats. Could that be implemented?

@andydelso
Copy link

andydelso commented Aug 25, 2021

It turns out that Gradle doesn't have a direct equivalent of Maven's exec:java goal. So the CLI commands cannot be translated 1:1 into Gradle. Instead, a new task or multiple tasks have to be defined in the project's build.gradle which then can be executed.

I think maybe you can get away with including the application plugin and setting the mainClass in the gradle(kotlin) build file:

plugins {
    application
    kotlin("jvm") version "1.5.0"
}

application {
    mainClass.set("com.microsoft.playwright.CLI")
}

...and then running this, but I could be wrong:

./gradlew run --args="install" // you can specify the browser here as well
./gradlew run --args="install-deps"

update:
Just tried both and then work along with browsing a page:
./gradlew run --args="open google.com"

@andydelso
Copy link

@jhyot and @yury-s - I think both an example gradle in both groovy and kotlin, along with these commands could be super useful in the docs! 😄

@yury-s
Copy link
Member

yury-s commented Aug 26, 2021

There are some neat setups on Gradle website that toggle between Groovy and Kotlin formats. Could that be implemented?

Should be possible and I think this is the way to go.

I think maybe you can get away with including the application plugin and setting the mainClass in the gradle(kotlin) build file:

I like how concise the command line is in that case, but I'm concerned that it may get in conflict with the actual "application" in the project. Perhaps it's not an issue (I'm not familiar enough with Gradle)?

@andydelso
Copy link

@yury-s I am able to run tests locally using Playwright with a similar gradle setup. What would be the best way to test this?

@jhyot
Copy link
Author

jhyot commented Sep 16, 2021

I like how concise the command line is in that case, but I'm concerned that it may get in conflict with the actual "application" in the project. Perhaps it's not an issue (I'm not familiar enough with Gradle)?

Yeah I would not use the application method as the main official way to use Playwright, because as you noted there can be only one application, and this might already be used by a project.

The best that I could come up with would be called something like this example command:

./gradlew playwright -Pargs="open --device='iPhone 11' wikipedia.org"

and this is the setup:

task playwright(type: JavaExec) {
  mainClass = 'com.microsoft.playwright.CLI'
  classpath sourceSets.main.runtimeClasspath
  if (project.hasProperty('args')) {
    args project.getProperty('args')
  }
}

@andydelso
Copy link

Yeah I would not use the application method as the main official way to use Playwright, because as you noted there can be only one application, and this might already be used by a project.

The application is actually the framework the user is wrapping around Playwright, and as I mentioned, this does not conflict. I was able to use exactly what I said locally in my own project. So I don't see the issue, but whatever is the best for the general user is going to be the right one, and that may not be mine 😆

@jhyot
Copy link
Author

jhyot commented Sep 21, 2021

Yeah I would not use the application method as the main official way to use Playwright, because as you noted there can be only one application, and this might already be used by a project.

The application is actually the framework the user is wrapping around Playwright, and as I mentioned, this does not conflict. I was able to use exactly what I said locally in my own project. So I don't see the issue, but whatever is the best for the general user is going to be the right one, and that may not be mine 😆

Not sure if we are maybe misunderstanding each other. I thought (but haven't actually checked) that if a project already uses the application plugin for its own purpose, you can't add another application for playwright.

If your project doesn't use the application, then sure it will work.

@mxschmitt mxschmitt added documentation Improvements or additions to documentation good first issue Good for newcomers labels Mar 21, 2022
@SergeyPirogov
Copy link

SergeyPirogov commented Jul 6, 2022

It turns out that Gradle doesn't have a direct equivalent of Maven's exec:java goal. So the CLI commands cannot be translated 1:1 into Gradle. Instead, a new task or multiple tasks have to be defined in the project's build.gradle which then can be executed.

I think maybe you can get away with including the application plugin and setting the mainClass in the gradle(kotlin) build file:

plugins {
    application
    kotlin("jvm") version "1.5.0"
}

application {
    mainClass.set("com.microsoft.playwright.CLI")
}

...and then running this, but I could be wrong:

./gradlew run --args="install" // you can specify the browser here as well ./gradlew run --args="install-deps"

update: Just tried both and then work along with browsing a page: ./gradlew run --args="open google.com"

This approach is working well!

@andydelso
Copy link

It turns out that Gradle doesn't have a direct equivalent of Maven's exec:java goal. So the CLI commands cannot be translated 1:1 into Gradle. Instead, a new task or multiple tasks have to be defined in the project's build.gradle which then can be executed.

I think maybe you can get away with including the application plugin and setting the mainClass in the gradle(kotlin) build file:

plugins {
    application
    kotlin("jvm") version "1.5.0"
}

application {
    mainClass.set("com.microsoft.playwright.CLI")
}

...and then running this, but I could be wrong:
./gradlew run --args="install" // you can specify the browser here as well ./gradlew run --args="install-deps"
update: Just tried both and then work along with browsing a page: ./gradlew run --args="open google.com"

This approach is working well!

Glad it is working for you.

@yury-s @jhyot would it be worth it to add this approach as an alternative much like the suggestion at the end of the linked #864 ?

@jhyot I am not sure what you mean. Basically your local framwork is an application that is leveraging the playwright CLI is what is happening if I am not mistaken.

@yury-s
Copy link
Member

yury-s commented Jul 8, 2022

@yury-s @jhyot would it be worth it to add this approach as an alternative much like the suggestion at the end of the linked #864 ?

Yes, we can add a guide providing some tips on how to use gradle + cli. Would you like to send a PR for that (the docs source is here)?

@jhyot
Copy link
Author

jhyot commented Jul 11, 2022

@jhyot I am not sure what you mean. Basically your local framwork is an application that is leveraging the playwright CLI is what is happening if I am not mistaken.

@ddaypunk
For example, if you have a single gradle module for your application (i.e. everything about the main application and all tests etc. is defined in the one gradle build file), and your application is already leveraging the application { } block for its own purposes (running the app in CLI); then you cannot add another application { } block just for Playwright. They would conflict.

For that reason, I don't recommend documenting the application { } method as the only or the main way to use Playwright CLI with gradle. The other way using a task (#571 (comment)) is more generic, because it works in any case.
I believe that many people just copy&paste the build file additions blindly (because most developers are not interested in the details of the build system), so displaying the application { } method as the first or only way would lead to breaking of some peoples' builds, which I consider bad.

I don't mind if the application { } method is described additionally as well, because it is convenient. As long as users know the alternatives.

But also, I would guess that because of the types of applications that are most interested in using Playwright (web apps), by far the majority of apps don't use the application block. So it is in the end of course a judgement call. I just wanted to make the implications clear.

@andydelso
Copy link

@jhyot If I can get to it, I would love to. Some interesting developments at work today, so I may not get to it for a bit.

@eneller
Copy link

eneller commented Feb 10, 2023

So i was looking to add this to the documentation, but the given example in the comment seems to only work with single-word commands?
Can anyone reproduce this? (using gradle 7.4)

./gradlew playwright -Pargs="open --device='iPhone 11' wikipedia.org"
task playwright(type: JavaExec) {
  mainClass = 'com.microsoft.playwright.CLI'
  classpath sourceSets.main.runtimeClasspath
  if (project.hasProperty('args')) {
    args project.getProperty('args')
  }
}

@jhyot
Copy link
Author

jhyot commented May 23, 2023

Actually, as I found out, the JavaExec task type supports the --args command line parameter (even without application plugin).

So this should work:

task playwright(type: JavaExec) {
  mainClass = 'com.microsoft.playwright.CLI'
  classpath sourceSets.main.runtimeClasspath  // or possibly sourceSets.test if Playwright is a test dependency only
}

And run like this:
./gradlew playwright --args="open --device='iPhone 11' wikipedia.org"

That should also fix the multiple-args problem as noticed by @eneller.

@parthasarma87
Copy link

parthasarma87 commented May 25, 2023

It turns out that Gradle doesn't have a direct equivalent of Maven's exec:java goal. So the CLI commands cannot be translated 1:1 into Gradle. Instead, a new task or multiple tasks have to be defined in the project's build.gradle which then can be executed.

I think maybe you can get away with including the application plugin and setting the mainClass in the gradle(kotlin) build file:

plugins {
    application
    kotlin("jvm") version "1.5.0"
}

application {
    mainClass.set("com.microsoft.playwright.CLI")
}

...and then running this, but I could be wrong:

./gradlew run --args="install" // you can specify the browser here as well ./gradlew run --args="install-deps"

update: Just tried both and then work along with browsing a page: ./gradlew run --args="open google.com"

Hey @ddaypunk , this works. Can you share an example on how it can be converted to a Gradle kotlin DSL task so that we can run the codegen when we do say ./gradlew codegen --args="open google.com" ? Essentially say we do not want to modify the main application run cli option , as We want the application to execute when We do gradlew run ,We would instead like to add a new task for trigger codegen.

@KotlinIsland
Copy link

FYI Kotlin is now the default for Gradle build files.

https://blog.gradle.org/kotlin-dsl-is-now-the-default-for-new-gradle-builds

@andydelso
Copy link

It turns out that Gradle doesn't have a direct equivalent of Maven's exec:java goal. So the CLI commands cannot be translated 1:1 into Gradle. Instead, a new task or multiple tasks have to be defined in the project's build.gradle which then can be executed.

I think maybe you can get away with including the application plugin and setting the mainClass in the gradle(kotlin) build file:

plugins {
    application
    kotlin("jvm") version "1.5.0"
}

application {
    mainClass.set("com.microsoft.playwright.CLI")
}

...and then running this, but I could be wrong:
./gradlew run --args="install" // you can specify the browser here as well ./gradlew run --args="install-deps"
update: Just tried both and then work along with browsing a page: ./gradlew run --args="open google.com"

Hey @ddaypunk , this works. Can you share an example on how it can be converted to a Gradle kotlin DSL task so that we can run the codegen when we do say ./gradlew codegen --args="open google.com" ? Essentially say we do not want to modify the main application run cli option , as We want the application to execute when We do gradlew run ,We would instead like to add a new task for trigger codegen.

If I am not mistaken, they are trying to avoid using the application plugin? A few previous comments shows using a task which is already in Kotlin DSL.

@jhyot
Copy link
Author

jhyot commented Jun 28, 2023

Hey @ddaypunk , this works. Can you share an example on how it can be converted to a Gradle kotlin DSL task so that we can run the codegen when we do say ./gradlew codegen --args="open google.com" ? Essentially say we do not want to modify the main application run cli option , as We want the application to execute when We do gradlew run ,We would instead like to add a new task for trigger codegen.

@parthasarma87 check my comment: #571 (comment)

It is in Groovy, but I think you can find out what the syntax in Kotlin is (I don't know). The key is to create the new task as type JavaExec. Then the --args also works for that task automatically, without needing to modify the main application.

@jfgreffier
Copy link
Contributor

jfgreffier commented Aug 6, 2023

First things first. I've made a branch with the changes suggested on the intro page for install
https://github.com/jfgreffier/playwright/tree/feat/gradle-docs

Shall we add Kotlin ? Kotlin only ?

Next step will be to add the alternatives to Playwright commands. For example : ./gradlew playwright --args="codegen demo.playwright.dev/todomvc"

@ardetrick
Copy link

First things first. I've made a branch with the changes suggested on the intro page for install https://github.com/jfgreffier/playwright/tree/feat/gradle-docs

Shall we add Kotlin ? Kotlin only ?

Thanks for getting this started @jfgreffier. I would support adding Kotlin as well, Groovy is so common that I think having both would be useful.

Here is the Kotlin code I have used for a project. Feel free to include it in your commit, or I can add one later if you choose not to add it.

// build.gradle.kts
// Usage: gradle playwright --args="help"
tasks.register<JavaExec>("playwright") {
    classpath(sourceSets["test"].runtimeClasspath)
    mainClass.set("com.microsoft.playwright.CLI")
}

@jfgreffier
Copy link
Contributor

jfgreffier commented Aug 10, 2023

Thanks @ardetrick I've updated my branch accordingly and created a PR.

I only documented CLI usage with Gradle in the installation page; I feel it's very redondant to add it next to each Maven example. I'm opened to suggestions or co-authoring the PR

@ardetrick
Copy link

I don't have much context on the rest of the example, but the gradle kotlin task looks good to me. thanks for adding it!

yury-s pushed a commit to microsoft/playwright that referenced this issue Aug 15, 2023
Docs update to install Playwright as a dependency with Gradle, also
introduce how to run Playwright CLI

```bash
./gradlew playwright --args="help"
```

Fixes [#571](microsoft/playwright-java#571)
Germandrummer92 pushed a commit to OctoMind-dev/playwright that referenced this issue Oct 27, 2023
Docs update to install Playwright as a dependency with Gradle, also
introduce how to run Playwright CLI

```bash
./gradlew playwright --args="help"
```

Fixes [microsoft#571](microsoft/playwright-java#571)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants