Skip to content

[KOB-52290] Feature/python pytest generator restart#60

Merged
d4rkwinz merged 2 commits intokobiton:masterfrom
mimosa767:feature/python-pytest-generator-restart
Apr 16, 2026
Merged

[KOB-52290] Feature/python pytest generator restart#60
d4rkwinz merged 2 commits intokobiton:masterfrom
mimosa767:feature/python-pytest-generator-restart

Conversation

@mimosa767
Copy link
Copy Markdown
Contributor

@mimosa767 mimosa767 commented Apr 15, 2026

Summary

Types of changes

What types of changes does your code introduce to this project? Put an x in the boxes that apply.

  • Bugfix.
  • New feature.
  • Documentation update.

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the pull request. If you are unsure about any of them, do not hesitate to ask. We are here to help! This is simply a reminder of what we are going to look for before merging your code.

  • I have read the CONTRIBUTING documentation.
  • I have rebased, and my remote branch is now up-to-date with the master branch of the upstream.
  • Lint and unit tests pass locally with my changes.
  • I have added tests that prove my changes are effective.
  • I have added the necessary documentation (if appropriate).

Further comments

mimosa767 and others added 2 commits April 15, 2026 05:39
…overage

Generated Python scripts were malformed in several ways: @classmethod landed
outside the class body, indent levels drifted with each device block causing
pytest to miss all but the first test function, finally was nested inside
except causing an immediate SyntaxError, JS true/false appeared as Python
literals, XPath selectors with double-quoted attributes broke string quoting,
and multi-device if/elif/else branches were nested inside each other.

Runtime template gaps were also fixed: missing AppiumBy/By imports in
test_app.py, deprecated webdriver.Remote API updated to AppiumOptions in
test_base.py, missing action helpers added (send_keys_to_active_element,
swipe_on_element, press_button_multiple, rotate_screen, set_location), port
handling corrected in config.py, and proxy auth switched from URL-embedded
credentials to an Authorization header in proxy_server.py.

A direct Python regression test (no gRPC) now generates a real zip from a
2-device fixture and runs ast.parse plus six structural checks over every .py
file to protect against recurrence.

Note: the pre-existing open-handles warning from the gRPC integration tests
in generate-script.test.js is unrelated and left for a separate cleanup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 15, 2026 15:07
@mimosa767
Copy link
Copy Markdown
Contributor Author

No documentation changes needed; this PR fixes Python script generation issues and adds regression coverage.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Python (pytest) script generator and templates to produce syntactically-correct, Appium-client-compatible output (notably around indentation, booleans, and driver initialization), and adds an integration fixture + validator to prevent regressions.

Changes:

  • Switch Python template driver creation to use AppiumOptions instead of passing raw desired capabilities.
  • Fix Python code generation issues: emit Python True/False, correct indentation handling (including finally:), and adjust locator generation to use instance device fields.
  • Add a Python pytest integration test that generates a script zip and validates output with a small Python-based validator.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/templates/python/test_base.py Updates driver initialization to AppiumOptions; expands helper APIs used by generated steps; updates element-finding to try multiple locators.
src/templates/python/test_app.py Adds required imports (AppiumBy, By) for generated locator tuples.
src/templates/python/proxy_server.py Changes proxy auth approach to use Authorization header instead of embedding creds in URL.
src/templates/python/config.py Fixes URL-with-auth construction when no port is present; keeps Basic auth helper.
src/services/python.js Fixes Python output correctness (indentation, True/False, locator quoting/branching) and generator indentation offsets.
tests/resource/python-pytest-input.json Adds a 2-device pytest fixture for integration testing.
tests/integration/python-pytest.test.js Adds integration test that generates a pytest zip and validates it.
tests/helpers/validate-python-output.py Adds validator to catch Python syntax/indentation and key content regressions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +38 to +40
# 1. Syntax check — ast.parse catches IndentationError, SyntaxError,
# wrong boolean literals, and broken string literals.
# ------------------------------------------------------------------
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validator docstring claims ast.parse() “catches wrong boolean literals”, but invalid Python booleans like true/false are parsed as names and won’t raise SyntaxError (they fail at runtime). Consider updating the comment to reflect that the dedicated regex check (section 3) is what catches JS boolean literals, while ast.parse() covers syntax/indentation only.

Copilot uses AI. Check for mistakes.
Comment on lines 15 to 21
if self.current_command_id:
separator = '&' if '?' in url else '?'
url = f"{url}{separator}baseCommandId={self.current_command_id}"

headers = {key: val for key, val in self.headers.items()}
headers['Authorization'] = Config.get_basic_auth_string()
req = Request(url, data=body, headers=headers, method=method)
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current_command_id is maintained on ProxyServer, but ProxyHandler.do_request() reads self.current_command_id where current_command_id is a class attribute on ProxyHandler. As a result, updates via TestBase.set_current_command_id() won't affect the handler and baseCommandId will never be appended. Consider wiring the value through self.server (custom HTTPServer with a current_command_id field) or making ProxyServer.current_command_id update ProxyHandler.current_command_id (e.g., via a property/setter).

Copilot uses AI. Check for mistakes.
return wait.until(EC.visibility_of_element_located(locator))
except Exception as e:
last_exception = e
raise last_exception
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit (non-blocking): The new multi-locator loop applies the full WebDriverWait timeout per locator sequentially, so worst case = N locators × timeout. For 2 locators with a 7s timeout, that's ~14s if none match.

The Java/Node.js/C# siblings handle this differently in their findElements — they set implicit wait to 0 (instant check), loop all locators quickly, then retry with a 5s interval, staying within the original timeout budget regardless of locator count.

Not a blocker for this PR since the focus is fixing broken generated code, but worth aligning with the sibling pattern in a follow-up.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is nice to have, I'm going to merge it so it does not block TE testing.

@d4rkwinz d4rkwinz changed the title Feature/python pytest generator restart [KOB-52290] Feature/python pytest generator restart Apr 16, 2026
@d4rkwinz
Copy link
Copy Markdown
Contributor

@mimosa767 Please help to add the prefix "ticket" next time on your PR. Thank you!

@d4rkwinz d4rkwinz merged commit 32561ab into kobiton:master Apr 16, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants