-
Notifications
You must be signed in to change notification settings - Fork 101
7 screen play #5
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
base: main
Are you sure you want to change the base?
Conversation
|
F |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review Summary by Optima AI Bot
I've reviewed this Screenplay pattern refactoring and found 6 issues that need attention before merging:
🚨 Critical Issues (1)
- Missing screenplay.pattern module: The entire PR imports from
screenplay.patternwhich doesn't exist in the repository. This will cause immediate import failures.
⚠️ High Priority Issues (2)
- XPath injection vulnerability: Dynamic XPath construction with unsanitized input in GitHub tasks
- Missing login verification: Authentication failures won't be detected until later in tests
📋 Medium Priority Issues (3)
- Flaky test risk: Hardcoded wait for 5th search result could fail with fewer results
- Inconsistent inheritance: One task class breaks the established pattern
- Missing newline: File doesn't end with newline (minor style issue)
Overall Assessment
The Screenplay pattern refactoring is well-structured and improves test readability significantly. However, the missing screenplay.pattern module is a blocker that must be resolved first. The security and reliability issues should also be addressed to ensure robust test execution.
Generated by automated code review • 6 detailed comments posted inline
| self.page = page | ||
| self.result_links = page.locator('a[data-testid="result-title-a"]') | ||
| self.search_input = page.locator('#search_form_input') | ||
|
No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing newline at end of file
This file is missing a newline character at the end. While this won't cause runtime errors, it violates POSIX standards and can cause issues with certain text processing tools and version control systems. Most Python linters and formatters will flag this as a code style issue.
Suggested fix:
self.search_input = page.locator('#search_form_input')References:
| from abc import ABC, abstractmethod | ||
| from interactions.duckduckgo.pages import ResultPage | ||
| from playwright.sync_api import Page | ||
| from screenplay.pattern import Actor, Question, Answer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing screenplay.pattern module will cause import failure 🚨 Critical
This file imports from 'screenplay.pattern' which doesn't exist in the repository. This is a critical blocker - the tests will fail immediately on import with a ModuleNotFoundError. The entire PR depends on this missing module, which needs to be either added to the repository or installed as a dependency in requirements.txt. Without this module defining Actor, Question, Answer, and Task classes, none of the refactored code will work.
Suggested fix:
# Option 1: Create screenplay/pattern.py in the repository
# Option 2: Add to requirements.txt if it's an external package:
screenplay-pattern>=1.0.0| class load_duckduckgo(DuckDuckGoTask): | ||
|
|
||
| def perform_on_page(self, _, page: Page) -> None: | ||
| page.goto(SearchPage.URL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded wait for 5th element may cause flaky tests
Waiting for exactly the 5th result (index 4) to appear is fragile and could cause test failures if search results return fewer items. This hardcoded wait assumes DuckDuckGo will always return at least 5 results, which may not be true for all searches or if the page structure changes. This can lead to timeout errors and flaky test behavior.
Suggested fix:
result_page.result_links.first.wait_for()
# Or wait for any results to be visible
# result_page.result_links.nth(0).wait_for()References:
| expect(page).to_have_title(self.title) | ||
|
|
||
|
|
||
| class verify_result_link_titles_contain(Task): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent class inheritance pattern
The verify_result_link_titles_contain class inherits directly from Task instead of DuckDuckGoTask like the other classes in this module. This breaks the established pattern and means it doesn't get the perform_on_page abstraction. This inconsistency can confuse maintainers and makes the codebase harder to understand. It appears to be intentional since it implements perform_as differently, but the reasoning isn't documented.
Suggested fix:
# This task needs direct Task inheritance because it uses asks_for() instead of page operations
class verify_result_link_titles_contain(Task):
# ... rest of implementation| self.note = note | ||
|
|
||
| def perform_on_page(self, actor: Actor, page: Page) -> None: | ||
| card_xpath = f'//div[@id="column-cards-{self.column_id}"]//p[contains(text(), "{self.note}")]' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
XPath injection vulnerability in dynamic locator construction
User-controlled input (column_id and note) is directly interpolated into XPath expressions without sanitization. If the 'note' parameter contains special XPath characters like quotes, parentheses, or brackets, it could break the XPath query or potentially be exploited for XPath injection. While this is a test framework and not production code, it can still cause test failures or unexpected behavior if notes contain special characters.
Suggested fix:
column_locator = page.locator(f'#column-cards-{self.column_id}')
card_locator = column_locator.locator('p', has_text=self.note)
expect(card_locator).to_be_visible()References:
| self.username = username | ||
| self.password = password | ||
|
|
||
| def perform_on_page(self, actor: Actor, page: Page) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling for login flow
The login task doesn't verify that login was successful before proceeding. If authentication fails (wrong credentials, CAPTCHA, 2FA required, etc.), the test will continue and fail later with confusing error messages. This makes debugging failed tests much harder because the root cause (failed login) is obscured by subsequent failures. Production GitHub accounts often have 2FA enabled, which would cause this login flow to fail silently.
Suggested fix:
def perform_on_page(self, actor: Actor, page: Page) -> None:
page.goto(f'https://github.com/login')
page.locator('id=login_field').fill(self.username)
page.locator('id=password').fill(self.password)
page.locator('input[name="commit"]').click()
# Verify login succeeded by checking for user avatar or dashboard
page.locator('[data-login="{}"]'.format(self.username)).wait_for(timeout=10000)References:
No description provided.