{"id":"c25b83cb-7d93-4af1-bb1d-4b2637d1080b","shortId":"UEybfg","kind":"skill","title":"playwright-java","tagline":"Scaffold, write, debug, and enhance enterprise-grade Playwright E2E tests in Java using Page Object Model, JUnit 5, Allure reporting, and parallel execution.","description":"# Playwright Java – Advanced Test Automation\n\n## Overview\n\nThis skill produces production-quality, enterprise-grade Playwright Java test code.\nIt enforces the Page Object Model (POM), strict locator strategies, thread-safe parallel\nexecution, and full Allure reporting integration. Targets Java 17+ and Playwright 1.44+.\n\nSupporting reference files are available for deeper topics:\n\n| Topic | File |\n|-------|------|\n| Maven POM, ConfigReader, Docker/CI setup | `references/config.md` |\n| Component pattern, dropdowns, uploads, waits | `references/page-objects.md` |\n| Full assertion API, soft assertions, visual testing | `references/assertions.md` |\n| Fixtures, test data factory, auth state, retry | `references/fixtures.md` |\n| Drop-in base class templates | `templates/BaseTest.java`, `templates/BasePage.java` |\n\n---\n\n## When to Use This Skill\n\n- Use when scaffolding a new Playwright Java project from scratch\n- Use when writing Page Object classes or JUnit 5 test classes\n- Use when the user asks about cross-browser testing, parallel execution, or Allure reports\n- Use when fixing flaky tests or replacing `Thread.sleep()` with proper waits\n- Use when setting up Playwright in CI/CD pipelines (GitHub Actions, Jenkins, Docker)\n- Use when combining API calls and UI assertions in a single test (hybrid testing)\n- Use when the user mentions \"POM pattern\", \"BrowserContext\", \"Playwright fixtures\", or \"traces\"\n\n---\n\n## How It Works\n\n### Step 1: Decide the Approach\n\nUse this matrix to pick the right pattern before writing any code:\n\n| User Request | Approach |\n|---|---|\n| New project from scratch | Full scaffold — see `references/config.md` |\n| Single feature test | POM page class + JUnit5 test class |\n| API + UI hybrid | `APIRequestContext` alongside `Page` |\n| Cross-browser | `@MethodSource` parameterized over browser names |\n| Flaky test fix | Replace `sleep` with `waitFor` / `waitForResponse` |\n| CI integration | `playwright install --with-deps` in pipeline |\n| Parallel execution | `junit-platform.properties` + `ThreadLocal` |\n| Rich reporting | Allure + Playwright trace + video recording |\n\n---\n\n### Step 2: Scaffold the Project Structure\n\nAlways use this layout when creating a new project:\n\n```\nsrc/\n├── test/\n│   ├── java/com/company/tests/\n│   │   ├── base/\n│   │   │   ├── BaseTest.java        ← templates/BaseTest.java\n│   │   │   └── BasePage.java        ← templates/BasePage.java\n│   │   ├── pages/\n│   │   │   └── LoginPage.java\n│   │   ├── tests/\n│   │   │   └── LoginTest.java\n│   │   ├── utils/\n│   │   │   ├── TestDataFactory.java\n│   │   │   └── WaitUtils.java\n│   │   └── config/\n│   │       └── ConfigReader.java\n│   └── resources/\n│       ├── test.properties\n│       ├── junit-platform.properties\n│       └── testdata/users.json\npom.xml\n```\n\n---\n\n### Step 3: Set Up Thread-Safe BaseTest\n\n```java\npublic class BaseTest {\n    protected static ThreadLocal<Playwright>     playwrightTL = new ThreadLocal<>();\n    protected static ThreadLocal<Browser>        browserTL    = new ThreadLocal<>();\n    protected static ThreadLocal<BrowserContext> contextTL    = new ThreadLocal<>();\n    protected static ThreadLocal<Page>           pageTL       = new ThreadLocal<>();\n\n    protected Page page() { return pageTL.get(); }\n\n    @BeforeEach\n    void setUp() {\n        Playwright playwright = Playwright.create();\n        playwrightTL.set(playwright);\n\n        Browser browser = resolveBrowser(playwright).launch(\n            new BrowserType.LaunchOptions()\n                .setHeadless(ConfigReader.isHeadless()));\n        browserTL.set(browser);\n\n        BrowserContext context = browser.newContext(new Browser.NewContextOptions()\n            .setViewportSize(1920, 1080)\n            .setRecordVideoDir(Paths.get(\"target/videos/\"))\n            .setLocale(\"en-US\"));\n        context.tracing().start(new Tracing.StartOptions()\n            .setScreenshots(true).setSnapshots(true));\n        contextTL.set(context);\n        pageTL.set(context.newPage());\n    }\n\n    @AfterEach\n    void tearDown(TestInfo testInfo) {\n        String name = testInfo.getDisplayName().replaceAll(\"[^a-zA-Z0-9]\", \"_\");\n        contextTL.get().tracing().stop(new Tracing.StopOptions()\n            .setPath(Paths.get(\"target/traces/\" + name + \".zip\")));\n        pageTL.get().close();\n        contextTL.get().close();\n        browserTL.get().close();\n        playwrightTL.get().close();\n    }\n\n    private BrowserType resolveBrowser(Playwright pw) {\n        return switch (System.getProperty(\"browser\", \"chromium\").toLowerCase()) {\n            case \"firefox\" -> pw.firefox();\n            case \"webkit\"  -> pw.webkit();\n            default        -> pw.chromium();\n        };\n    }\n}\n```\n\n---\n\n### Step 4: Build Page Object Classes\n\n```java\npublic class LoginPage extends BasePage {\n\n    // Declare ALL locators as fields — never inline in action methods\n    private final Locator emailInput;\n    private final Locator passwordInput;\n    private final Locator loginButton;\n    private final Locator errorMessage;\n\n    public LoginPage(Page page) {\n        super(page);\n        emailInput    = page.getByLabel(\"Email address\");\n        passwordInput = page.getByLabel(\"Password\");\n        loginButton   = page.getByRole(AriaRole.BUTTON,\n                            new Page.GetByRoleOptions().setName(\"Sign in\"));\n        errorMessage  = page.getByTestId(\"login-error\");\n    }\n\n    @Override protected String getUrl() { return \"/login\"; }\n\n    // Navigation methods return the next Page Object — enables fluent chaining\n    public DashboardPage loginAs(String email, String password) {\n        fill(emailInput, email);\n        fill(passwordInput, password);\n        clickAndWaitForNav(loginButton);\n        return new DashboardPage(page);\n    }\n\n    public LoginPage loginExpectingError(String email, String password) {\n        fill(emailInput, email);\n        fill(passwordInput, password);\n        loginButton.click();\n        errorMessage.waitFor();\n        return this;\n    }\n\n    public String getErrorMessage() { return errorMessage.textContent(); }\n}\n```\n\n---\n\n### Step 5: Write Tests with Allure Annotations\n\n```java\n@ExtendWith(AllureJunit5.class)\nclass LoginTest extends BaseTest {\n\n    private LoginPage loginPage;\n\n    @BeforeEach\n    void openLoginPage() {\n        loginPage = new LoginPage(page());\n        loginPage.navigate();\n    }\n\n    @Test\n    @Severity(SeverityLevel.BLOCKER)\n    @DisplayName(\"Valid credentials redirect to dashboard\")\n    void shouldLoginWithValidCredentials() {\n        User user = TestDataFactory.getDefaultUser();\n        DashboardPage dash = loginPage.loginAs(user.email(), user.password());\n\n        assertThat(page()).hasURL(Pattern.compile(\".*/dashboard\"));\n        assertThat(dash.getWelcomeBanner()).containsText(\"Welcome, \" + user.firstName());\n    }\n\n    @Test\n    void shouldShowErrorOnInvalidCredentials() {\n        loginPage.loginExpectingError(\"bad@test.com\", \"wrongpass\");\n\n        SoftAssertions softly = new SoftAssertions();\n        softly.assertThat(loginPage.getErrorMessage()).contains(\"Invalid email or password\");\n        softly.assertThat(page()).hasURL(Pattern.compile(\".*/login\"));\n        softly.assertAll();\n    }\n\n    @ParameterizedTest\n    @MethodSource(\"provideInvalidCredentials\")\n    void shouldRejectInvalidCredentials(String email, String password, String expectedError) {\n        loginPage.loginExpectingError(email, password);\n        assertThat(loginPage.getErrorMessage()).containsText(expectedError);\n    }\n\n    static Stream<Arguments> provideInvalidCredentials() {\n        return Stream.of(\n            Arguments.of(\"\", \"password123\", \"Email is required\"),\n            Arguments.of(\"user@test.com\", \"\", \"Password is required\"),\n            Arguments.of(\"notanemail\", \"pass\", \"Invalid email format\")\n        );\n    }\n}\n```\n\n---\n\n## Examples\n\n### Example 1: API + UI Hybrid Test\n\n```java\n@Test\nvoid shouldDisplayNewlyCreatedOrder() {\n    // Arrange via API — faster than navigating through UI\n    APIRequestContext api = page().context().request();\n    APIResponse response = api.post(\"/api/orders\",\n        RequestOptions.create()\n            .setHeader(\"Authorization\", \"Bearer \" + authToken)\n            .setData(Map.of(\"productId\", \"SKU-001\", \"quantity\", 2)));\n    assertThat(response).isOK();\n\n    String orderId = new JsonParser().parse(response.text())\n        .getAsJsonObject().get(\"id\").getAsString();\n\n    OrdersPage orders = new OrdersPage(page());\n    orders.navigate();\n    assertThat(orders.getOrderRowById(orderId)).isVisible();\n}\n```\n\n### Example 2: Network Mocking\n\n```java\n@Test\nvoid shouldHandleApiFailureGracefully() {\n    page().route(\"**/api/products\", route -> route.fulfill(\n        new Route.FulfillOptions()\n            .setStatus(503)\n            .setBody(\"{\\\"error\\\":\\\"Service Unavailable\\\"}\")\n            .setContentType(\"application/json\")));\n\n    ProductsPage products = new ProductsPage(page());\n    products.navigate();\n\n    assertThat(products.getErrorBanner())\n        .hasText(\"We're having trouble loading products. Please try again.\");\n}\n```\n\n### Example 3: Parallel Cross-Browser Test\n\n```java\n@ParameterizedTest\n@MethodSource(\"browsers\")\nvoid shouldRenderCheckoutOnAllBrowsers(String browserName) {\n    System.setProperty(\"browser\", browserName);\n    new CheckoutPage(page()).navigate();\n    assertThat(page().locator(\".checkout-form\")).isVisible();\n}\n\nstatic Stream<String> browsers() {\n    return Stream.of(\"chromium\", \"firefox\", \"webkit\");\n}\n```\n\n### Example 4: Parallel Execution Config\n\n```properties\n# src/test/resources/junit-platform.properties\njunit.jupiter.execution.parallel.enabled=true\njunit.jupiter.execution.parallel.mode.default=concurrent\njunit.jupiter.execution.parallel.config.strategy=fixed\njunit.jupiter.execution.parallel.config.fixed.parallelism=4\n```\n\n### Example 5: GitHub Actions CI Pipeline\n\n```yaml\n- name: Install Playwright browsers\n  run: mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args=\"install --with-deps\"\n\n- name: Run tests\n  run: mvn test -Dbrowser=${{ matrix.browser }} -Dheadless=true\n\n- name: Upload traces on failure\n  uses: actions/upload-artifact@v4\n  if: failure()\n  with:\n    name: playwright-traces\n    path: target/traces/\n\n- name: Upload Allure results\n  uses: actions/upload-artifact@v4\n  if: always()\n  with:\n    name: allure-results\n    path: target/allure-results/\n```\n\n---\n\n## Best Practices\n\n- ✅ Use `ThreadLocal<Page>` for every parallel-safe test suite\n- ✅ Declare all `Locator` fields at the top of the Page Object class\n- ✅ Return the next Page Object from navigation methods (fluent chaining)\n- ✅ Use `assertThat(locator)` — it auto-retries until timeout\n- ✅ Use `getByRole`, `getByLabel`, `getByTestId` as first-choice locators\n- ✅ Start tracing in `@BeforeEach` and stop with a file path in `@AfterEach`\n- ✅ Use `SoftAssertions` when validating multiple fields on a single page\n- ✅ Set up saved auth state (`storageState`) to skip login across test classes\n- ❌ Never use `Thread.sleep()` — replace with `waitFor()` or `waitForResponse()`\n- ❌ Never hardcode base URLs — always use `ConfigReader.getBaseUrl()`\n- ❌ Never create a `Playwright` instance inside a Page Object\n- ❌ Never use XPath for dynamic or frequently changing elements\n\n---\n\n## Common Pitfalls\n\n- **Problem:** Tests fail randomly in parallel mode\n  **Solution:** Ensure every test creates its own `Playwright → Browser → BrowserContext → Page` chain via `ThreadLocal`. Never share a `Page` across threads.\n\n- **Problem:** `assertThat(locator).isVisible()` times out even when the element appears\n  **Solution:** Increase timeout with `.setTimeout(10_000)` or raise `context.setDefaultTimeout()` in `BaseTest`.\n\n- **Problem:** `Thread.sleep(2000)` was added but tests are still flaky\n  **Solution:** Replace with `page.waitForResponse(\"**/api/endpoint\", () -> action())` or `assertThat(locator).hasText(\"Done\")` which polls automatically.\n\n- **Problem:** Playwright trace zip is empty or missing\n  **Solution:** Ensure `tracing().start()` is called before test actions and `tracing().stop()` is in `@AfterEach` — not `@AfterAll`.\n\n- **Problem:** Allure report is blank or missing steps\n  **Solution:** Add the AspectJ agent to `maven-surefire-plugin` `<argLine>` in `pom.xml` — see `references/config.md` for the exact snippet.\n\n- **Problem:** `storageState` auth file is stale and tests redirect to login\n  **Solution:** Re-run `AuthSetup` to regenerate `target/auth/user-state.json` before the suite, or add a `@BeforeAll` that conditionally refreshes it.\n\n---\n\n## Related Skills\n\n- `@rest-assured-java` — Use for pure API test suites without any UI interaction\n- `@selenium-java` — Legacy alternative; prefer Playwright for all new projects\n- `@allure-reporting` — Deep-dive into Allure annotations, categories, and history trends\n- `@testcontainers-java` — Use alongside this skill when tests need a live database or service\n- `@github-actions-ci` — For building complete multi-browser matrix CI pipelines\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["playwright","java","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-playwright-java","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/playwright-java","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34616 github stars · SKILL.md body (13,298 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-23T00:51:23.961Z","embedding":null,"createdAt":"2026-04-18T21:42:28.134Z","updatedAt":"2026-04-23T00:51:23.961Z","lastSeenAt":"2026-04-23T00:51:23.961Z","tsv":"'-001':740 '/api/endpoint':1109 '/api/orders':730 '/api/products':776 '/dashboard':635 '/login':535,662 '000':1089 '1':213,705 '1.44':72 '10':1088 '1080':395 '17':69 '1920':394 '2':292,742,767 '2000':1097 '3':329,808 '4':467,845,858 '5':22,142,588,860 '503':782 '9':428 'a-za-z0':424 'across':1007,1070 'action':180,486,862,1110,1135,1257 'actions/upload-artifact':898,914 'ad':1099 'add':1153,1193 'address':513 'advanc':30 'afteral':1143 'aftereach':415,987,1141 'agent':1156 'allur':23,64,158,286,592,911,921,1145,1228,1234 'allure-report':1227 'allure-result':920 'allurejunit5.class':596 'alongsid':253,1244 'altern':1220 'alway':297,917,1022 'annot':593,1235 'api':97,186,249,706,716,723,1209 'api.post':729 'apirequestcontext':252,722 'apirespons':727 'appear':1082 'application/json':788 'approach':216,231 'arguments.of':687,692,697 'ariarole.button':519 'arrang':714 'ask':149,1301 'aspectj':1155 'assert':96,99,190 'assertthat':631,636,678,743,762,795,829,959,1073,1112 'assur':1204 'auth':107,1001,1172 'author':733 'authsetup':1185 'authtoken':735 'auto':963 'auto-retri':962 'autom':32 'automat':1118 'avail':77 'bad@test.com':645 'base':114,309,1020 'basepag':477 'basepage.java':312 'basetest':335,339,600,1094 'basetest.java':310 'bearer':734 'beforeal':1195 'beforeeach':369,604,979 'best':925 'blank':1148 'boundari':1309 'browser':153,257,261,377,378,387,455,812,817,823,838,869,1060,1264 'browser.newcontext':390 'browser.newcontextoptions':392 'browsercontext':204,388,1061 'browsernam':821,824 'browsertl':349 'browsertl.get':443 'browsertl.set':386 'browsertyp':448 'browsertype.launchoptions':383 'build':468,1260 'call':187,1132 'case':458,461 'categori':1236 'chain':545,957,1063 'chang':1041 'checkout':833 'checkout-form':832 'checkoutpag':826 'choic':974 'chromium':456,841 'ci':271,863,1258,1266 'ci/cd':177 'clarif':1303 'class':115,139,144,245,248,338,471,474,597,947,1009 'clear':1276 'clickandwaitfornav':559 'close':440,442,444,446 'code':46,228 'com.microsoft.playwright.cli':876 'combin':185 'common':1043 'complet':1261 'compon':89 'concurr':854 'condit':1197 'config':321,848 'configread':85 'configreader.getbaseurl':1024 'configreader.isheadless':385 'configreader.java':322 'contain':653 'containstext':638,680 'context':389,412,725 'context.newpage':414 'context.setdefaulttimeout':1092 'context.tracing':403 'contexttl':355 'contexttl.get':429,441 'contexttl.set':411 'creat':302,1026,1056 'credenti':617 'criteria':1312 'cross':152,256,811 'cross-brows':151,255,810 'dash':627 'dash.getwelcomebanner':637 'dashboard':620 'dashboardpag':547,563,626 'data':105 'databas':1252 'dbrowser':888 'debug':6 'decid':214 'declar':478,936 'deep':1231 'deep-div':1230 'deeper':79 'default':464 'dep':277,881 'describ':1280 'dexec.args':877 'dexec.mainclass':875 'dheadless':890 'displaynam':615 'dive':1232 'docker':182 'docker/ci':86 'done':1115 'drop':112 'drop-in':111 'dropdown':91 'dynam':1038 'e':874 'e2e':13 'element':1042,1081 'email':512,550,555,569,574,655,670,676,689,701 'emailinput':491,510,554,573 'empti':1124 'en':401 'en-us':400 'enabl':543 'enforc':48 'enhanc':8 'ensur':1053,1128 'enterpris':10,41 'enterprise-grad':9,40 'environ':1292 'environment-specif':1291 'error':529,784 'errormessag':503,525 'errormessage.textcontent':586 'errormessage.waitfor':579 'even':1078 'everi':930,1054 'exact':1168 'exampl':703,704,766,807,844,859 'exec':872 'execut':27,61,156,281,847 'expectederror':674,681 'expert':1297 'extend':476,599 'extendwith':595 'factori':106 'fail':1047 'failur':896,901 'faster':717 'featur':241 'field':482,939,993 'file':75,82,984,1173 'fill':553,556,572,575 'final':489,493,497,501 'firefox':459,842 'first':973 'first-choic':972 'fix':162,265,856 'fixtur':103,206 'flaki':163,263,1104 'fluent':544,956 'form':834 'format':702 'frequent':1040 'full':63,95,236 'get':753 'getasjsonobject':752 'getasstr':755 'getbylabel':969 'getbyrol':968 'getbytestid':970 'geterrormessag':584 'geturl':533 'github':179,861,1256 'github-actions-ci':1255 'grade':11,42 'hardcod':1019 'hastext':797,1114 'hasurl':633,660 'histori':1238 'hybrid':195,251,708 'id':754 'increas':1084 'inlin':484 'input':1306 'insid':1030 'instal':274,867,878 'instanc':1029 'integr':66,272 'interact':1215 'invalid':654,700 'isok':745 'isvis':765,835,1075 'java':3,16,29,44,68,130,336,472,594,710,770,814,873,1205,1218,1242 'java/com/company/tests':308 'jenkin':181 'jsonpars':749 'junit':21,141 'junit-platform.properties':282,325 'junit.jupiter.execution.parallel.config.fixed.parallelism':857 'junit.jupiter.execution.parallel.config.strategy':855 'junit.jupiter.execution.parallel.enabled':851 'junit.jupiter.execution.parallel.mode.default':853 'junit5':246 'launch':381 'layout':300 'legaci':1219 'limit':1268 'live':1251 'load':802 'locat':55,480,490,494,498,502,831,938,960,975,1074,1113 'login':528,1006,1180 'login-error':527 'logina':548 'loginbutton':499,517,560 'loginbutton.click':578 'loginexpectingerror':567 'loginpag':475,505,566,602,603,607,609 'loginpage.geterrormessage':652,679 'loginpage.java':315 'loginpage.loginas':628 'loginpage.loginexpectingerror':644,675 'loginpage.navigate':611 'logintest':598 'logintest.java':317 'map.of':737 'match':1277 'matrix':219,1265 'matrix.browser':889 'maven':83,1159 'maven-surefire-plugin':1158 'mention':201 'method':487,537,955 'methodsourc':258,665,816 'miss':1126,1150,1314 'mock':769 'mode':1051 'model':20,52 'multi':1263 'multi-brows':1262 'multipl':992 'mvn':871,886 'name':262,421,437,866,882,892,903,909,919 'navig':536,719,828,954 'need':1249 'network':768 'never':483,1010,1018,1025,1034,1066 'new':128,232,304,344,350,356,362,382,391,405,432,520,562,608,649,748,758,779,791,825,1225 'next':540,950 'notanemail':698 'object':19,51,138,470,542,946,952,1033 'openloginpag':606 'order':757 'orderid':747,764 'orders.getorderrowbyid':763 'orders.navigate':761 'orderspag':756,759 'output':1286 'overrid':530 'overview':33 'page':18,50,137,244,254,314,365,366,469,506,507,509,541,564,610,632,659,724,760,774,793,827,830,945,951,997,1032,1062,1069 'page.getbylabel':511,515 'page.getbyrole':518 'page.getbyroleoptions':521 'page.getbytestid':526 'page.waitforresponse':1108 'pagetl':361 'pagetl.get':368,439 'pagetl.set':413 'parallel':26,60,155,280,809,846,932,1050 'parallel-saf':931 'parameter':259 'parameterizedtest':664,815 'pars':750 'pass':699 'password':516,552,558,571,577,657,672,677,694 'password123':688 'passwordinput':495,514,557,576 'path':907,923,985 'paths.get':397,435 'pattern':90,203,224 'pattern.compile':634,661 'permiss':1307 'pick':221 'pipelin':178,279,864,1267 'pitfal':1044 'playwright':2,12,28,43,71,129,175,205,273,287,372,373,376,380,450,868,905,1028,1059,1120,1222 'playwright-java':1 'playwright-trac':904 'playwright.create':374 'playwrighttl':343 'playwrighttl.get':445 'playwrighttl.set':375 'pleas':804 'plugin':1161 'poll':1117 'pom':53,84,202,243 'pom.xml':327,1163 'practic':926 'prefer':1221 'privat':447,488,492,496,500,601 'problem':1045,1072,1095,1119,1144,1170 'produc':36 'product':38,790,803 'productid':738 'production-qu':37 'products.geterrorbanner':796 'products.navigate':794 'productspag':789,792 'project':131,233,295,305,1226 'proper':169 'properti':849 'protect':340,346,352,358,364,531 'provideinvalidcredenti':666,684 'public':337,473,504,546,565,582 'pure':1208 'pw':451 'pw.chromium':465 'pw.firefox':460 'pw.webkit':463 'qualiti':39 'quantiti':741 'rais':1091 'random':1048 're':799,1183 're-run':1182 'record':290 'redirect':618,1178 'refer':74 'references/assertions.md':102 'references/config.md':88,239,1165 'references/fixtures.md':110 'references/page-objects.md':94 'refresh':1198 'regener':1187 'relat':1200 'replac':166,266,1013,1106 'replaceal':423 'report':24,65,159,285,1146,1229 'request':230,726 'requestoptions.create':731 'requir':691,696,1305 'resolvebrows':379,449 'resourc':323 'respons':728,744 'response.text':751 'rest':1203 'rest-assured-java':1202 'result':912,922 'retri':109,964 'return':367,452,534,538,561,580,585,685,839,948 'review':1298 'rich':284 'right':223 'rout':775,777 'route.fulfill':778 'route.fulfilloptions':780 'run':870,883,885,1184 'safe':59,334,933 'safeti':1308 'save':1000 'scaffold':4,126,237,293 'scope':1279 'scratch':133,235 'see':238,1164 'selenium':1217 'selenium-java':1216 'servic':785,1254 'set':173,330,998 'setbodi':783 'setcontenttyp':787 'setdata':736 'sethead':732 'setheadless':384 'setlocal':399 'setnam':522 'setpath':434 'setrecordvideodir':396 'setscreenshot':407 'setsnapshot':409 'setstatus':781 'settimeout':1087 'setup':87,371 'setviewports':393 'sever':613 'severitylevel.blocker':614 'share':1067 'shoulddisplaynewlycreatedord':713 'shouldhandleapifailuregrac':773 'shouldloginwithvalidcredenti':622 'shouldrejectinvalidcredenti':668 'shouldrendercheckoutonallbrows':819 'shouldshowerroroninvalidcredenti':643 'sign':523 'singl':193,240,996 'skill':35,123,1201,1246,1271 'skill-playwright-java' 'skip':1005 'sku':739 'sleep':267 'snippet':1169 'soft':98,648 'softassert':647,650,989 'softly.assertall':663 'softly.assertthat':651,658 'solut':1052,1083,1105,1127,1152,1181 'source-sickn33' 'specif':1293 'src':306 'src/test/resources/junit-platform.properties':850 'stale':1175 'start':404,976,1130 'state':108,1002 'static':341,347,353,359,682,836 'step':212,291,328,466,587,1151 'still':1103 'stop':431,981,1138,1299 'storagest':1003,1171 'strategi':56 'stream':683,837 'stream.of':686,840 'strict':54 'string':420,532,549,551,568,570,583,669,671,673,746,820 'structur':296 'substitut':1289 'success':1311 'suit':935,1191,1211 'super':508 'support':73 'surefir':1160 'switch':453 'system.getproperty':454 'system.setproperty':822 'target':67 'target/allure-results':924 'target/auth/user-state.json':1188 'target/traces':436,908 'target/videos':398 'task':1275 'teardown':417 'templat':116 'templates/basepage.java':118,313 'templates/basetest.java':117,311 'test':14,31,45,101,104,143,154,164,194,196,242,247,264,307,316,590,612,641,709,711,771,813,884,887,934,1008,1046,1055,1101,1134,1177,1210,1248,1295 'test.properties':324 'testcontain':1241 'testcontainers-java':1240 'testdata/users.json':326 'testdatafactory.getdefaultuser':625 'testdatafactory.java':319 'testinfo':418,419 'testinfo.getdisplayname':422 'thread':58,333,1071 'thread-saf':57,332 'thread.sleep':167,1012,1096 'threadloc':283,342,345,348,351,354,357,360,363,928,1065 'time':1076 'timeout':966,1085 'tolowercas':457 'top':942 'topic':80,81 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'trace':208,288,430,894,906,977,1121,1129,1137 'tracing.startoptions':406 'tracing.stopoptions':433 'treat':1284 'trend':1239 'tri':805 'troubl':801 'true':408,410,852,891 'ui':189,250,707,721,1214 'unavail':786 'upload':92,893,910 'url':1021 'us':402 'use':17,121,124,134,145,160,171,183,197,217,298,897,913,927,958,967,988,1011,1023,1035,1206,1243,1269 'user':148,200,229,623,624 'user.email':629 'user.firstname':640 'user.password':630 'user@test.com':693 'util':318 'v4':899,915 'valid':616,991,1294 'via':715,1064 'video':289 'visual':100 'void':370,416,605,621,642,667,712,772,818 'wait':93,170 'waitfor':269,1015 'waitforrespons':270,1017 'waitutils.java':320 'webkit':462,843 'welcom':639 'with-dep':275,879 'without':1212 'work':211 'write':5,136,226,589 'wrongpass':646 'xpath':1036 'yaml':865 'z0':427 'za':426 'zip':438,1122","prices":[{"id":"533a1e12-5167-4538-bce3-261ebdcf0a55","listingId":"c25b83cb-7d93-4af1-bb1d-4b2637d1080b","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:42:28.134Z"}],"sources":[{"listingId":"c25b83cb-7d93-4af1-bb1d-4b2637d1080b","source":"github","sourceId":"sickn33/antigravity-awesome-skills/playwright-java","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/playwright-java","isPrimary":false,"firstSeenAt":"2026-04-18T21:42:28.134Z","lastSeenAt":"2026-04-23T00:51:23.961Z"}],"details":{"listingId":"c25b83cb-7d93-4af1-bb1d-4b2637d1080b","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"playwright-java","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34616,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-22T06:40:00Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"bcde29cd3226943ba8a01c8a98f44e88d6806a7c","skill_md_path":"skills/playwright-java/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/playwright-java"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"playwright-java","description":"Scaffold, write, debug, and enhance enterprise-grade Playwright E2E tests in Java using Page Object Model, JUnit 5, Allure reporting, and parallel execution."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/playwright-java"},"updatedAt":"2026-04-23T00:51:23.961Z"}}