Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions lib/galaxy/selenium/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,26 @@ def __init__(self, from_dict: Optional[dict] = None) -> None:
self.url = from_dict.get("local_galaxy_url", "http://localhost:8080")
self.target_url_from_selenium = from_dict.get("selenium_galaxy_url", self.url)
self.timeout_multiplier = from_dict.get("timeout_multiplier", 1)
# Optional properties...
self.login_email = from_dict.get("login_email", "")
self.login_password = from_dict.get("login_password", "")

def _screenshot_path(self, label, extension=".png"):
return label + extension

# mirror TestWithSelenium method for doing this but use the config.
def login(self):
if self.login_email:
assert self.login_password, "If login_email is set, a password must be set also with login_password"
self.home()
self.submit_login(
email=self.login_email,
password=self.login_password,
assert_valid=True,
)
else:
self.register()


def init(config=None, clazz=GalaxySeleniumContextImpl) -> GalaxySeleniumContext:
if os.path.exists("galaxy_selenium_context.yml"):
Expand Down
159 changes: 159 additions & 0 deletions lib/galaxy_test/selenium/.claude/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Claude Code Configuration for Galaxy Selenium Tests

This directory contains Claude Code configuration and slash commands for working with Galaxy's Selenium test suite.

## CLAUDE.md

The `CLAUDE.md` file in the parent directory (`../CLAUDE.md`) provides comprehensive documentation about Galaxy Selenium testing conventions. It includes:

- Test structure and base classes
- Common patterns (login, navigation, data upload)
- Decorator usage (`@selenium_test`, `@managed_history`, `@requires_admin`)
- Component system access
- Helper methods and wait types
- Accessibility testing guidelines
- Complete test templates for different scenarios

**Purpose**: This file serves as context for Claude Code when writing or modifying Selenium tests, ensuring consistency with Galaxy's testing conventions.

## Slash Commands

### Direct Test Creation

#### `/new-selenium-test`

Bootstrap a new Selenium test file from scratch.

**Usage:**
```
/new-selenium-test <feature description>
```

**Examples:**
```
/new-selenium-test workflow import with accessibility testing
/new-selenium-test admin user management features
/new-selenium-test dataset metadata editing with managed history
```

**What it does:**
- Creates a new test file with proper structure
- Includes appropriate imports and decorators
- Follows Galaxy naming conventions
- Uses correct template based on requirements
- Asks clarifying questions if needed

#### `/add-selenium-test`

Add new test methods to an existing Selenium test file.

**Usage:**
```
/add-selenium-test <description and target file>
```

**Examples:**
```
/add-selenium-test Add a test for tag filtering to test_history_panel.py
/add-selenium-test Add admin test for user deletion to test_admin_app.py
/add-selenium-test Add dataset copy test with managed history to test_dataset_edit.py
```

**What it does:**
- Reads existing file to match style
- Adds properly structured test methods
- Updates imports if necessary
- Maintains consistency with existing code

### Interactive Jupyter Workflow

For complex tests or when you need to explore the DOM interactively, use the Jupyter notebook workflow:

#### `/setup-selenium-test-notebook`

Create a Jupyter notebook for interactively prototyping a Selenium test.

**Usage:**
```
/setup-selenium-test-notebook <feature description OR GitHub PR>
```

**Examples (text mode):**
```
/setup-selenium-test-notebook dataset metadata editing
/setup-selenium-test-notebook workflow import from URL
/setup-selenium-test-notebook admin user quota management
```

**Examples (GitHub PR mode):**
```
/setup-selenium-test-notebook https://github.com/galaxyproject/galaxy/pull/12345
/setup-selenium-test-notebook #12345
/setup-selenium-test-notebook 12345
```

**What it does:**
- Fetches PR context (if PR mode): description, screenshots, author
- Launches research subagent to find similar existing tests
- Creates a prototype notebook in `jupyter/` directory
- Includes PR context, example code, and starter code
- Prints complete setup instructions

**Workflow:**
1. Run `/setup-selenium-test-notebook <feature>` to create notebook
2. Follow printed instructions to start Jupyter
3. Prototype test interactively with screenshots
4. Run `/extract-selenium-test` when done to convert to test file

#### `/extract-selenium-test`

Extract test code from a Jupyter notebook and convert to a proper test file.

**Usage:**
```
/extract-selenium-test <notebook path or description>
```

**Examples:**
```
/extract-selenium-test from jupyter/test_prototype_dataset_metadata.ipynb
/extract-selenium-test jupyter/test_prototype_workflow_import.ipynb as test_workflow_import
/extract-selenium-test notebook test_prototype_admin_users.ipynb
```

**What it does:**
- Reads notebook cells (skipping initialization)
- Transforms `gx_selenium_context` to `self`
- Detects required decorators and attributes
- Creates properly structured Pytest test file for the Selenium test suite
- Groups related cells into test methods

## Getting Started

### Quick Start (Direct Creation)

For straightforward tests with known requirements:

1. **Read `../CLAUDE.md`** to understand Galaxy Selenium testing conventions
2. **Use `/new-selenium-test <description>`** to create a new test file
3. **Use `/add-selenium-test <description>`** to extend an existing test file
4. **Run** with `pytest lib/galaxy_test/selenium/test_<your_file>.py`

### Interactive Development (Jupyter Workflow)

For complex tests or DOM exploration:

1. **Create notebook**: `/setup-selenium-test-notebook <description>`
2. **Start Galaxy & Jupyter** following the printed instructions
3. **Prototype interactively** in the notebook with live screenshots
4. **Extract to test**: `/extract-selenium-test <notebook_path>`
5. **Run** with `pytest lib/galaxy_test/selenium/test_<your_file>.py`

## Tips

- **Be specific** in command descriptions (mention admin access, managed history, etc.)
- **Use Jupyter workflow** when you need to explore the DOM or iterate quickly
- **Use direct creation** when you know exactly what needs to be tested
- Commands will **ask clarifying questions** if your request is ambiguous
- **Review generated code** to ensure it meets your specific needs
- **Reference existing tests** in the parent directory for patterns and examples
91 changes: 91 additions & 0 deletions lib/galaxy_test/selenium/.claude/commands/add-selenium-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
description: Add a new test method to an existing Galaxy Selenium test file
---

The user input can be provided directly or as a command argument - you **MUST** consider it before proceeding.

User input:

$ARGUMENTS

## Context

You are adding a new test method to an existing Selenium test file in the Galaxy test suite. Read the CLAUDE.md file in this directory for complete context on Galaxy Selenium testing conventions.

## Task

Add one or more new test methods to an existing test file based on the user's description. The user should specify:
- Which test file to modify (e.g., `test_history_panel.py`)
- What scenario(s) to test
- Any special requirements (managed history, admin access, etc.)

## Requirements

1. **Read CLAUDE.md** in the current directory for full context

2. **Read the target test file** to understand:
- Existing class structure and attributes
- Import statements already present
- Coding style and patterns used
- Helper methods defined in the class

3. **Match the existing style**:
- Use same patterns as other methods in the class
- Follow same naming conventions
- Maintain consistent indentation and spacing
- Add similar docstrings

4. **Add necessary imports** if new decorators/modules are needed:
- `managed_history` if using `@managed_history`
- `requires_admin` if using `@requires_admin`
- Any other decorators from `galaxy.selenium.navigates_galaxy`

5. **Use appropriate decorators**:
- Always use `@selenium_test`
- Add `@managed_history` if the test needs predictable HIDs
- Add `@requires_admin` if testing admin features
- Add `@edit_details` or other navigation decorators as needed

6. **Follow test structure**:
- Clear, descriptive method name: `test_<specific_scenario>`
- Docstring explaining what is being tested
- Proper setup and navigation
- Clear assertions
- Screenshots if helpful (use `self.screenshot("description")`)

7. **Respect class attributes**:
- If class has `ensure_registered = True`, user is already logged in
- If class has `run_as_admin = True`, tests run as admin
- Use these to simplify test setup

## Output

1. **Confirm the target**:
- Which file will be modified
- What test method(s) will be added

2. **Add the test method(s)** to the appropriate class

3. **Update imports** if needed

4. **Explain what was added**:
- What the new test does
- Why certain decorators were used
- How it fits with existing tests
- How to run just this new test

## Example Usage

```
/add-test Add a test for tag filtering to test_history_panel.py
/add-test Add admin test for user deletion to test_admin_app.py
/add-test Add dataset copy test with managed history to test_dataset_edit.py
```

## Notes

- Always read the existing file first to match its style
- Don't duplicate existing test scenarios
- Keep tests independent and focused
- Consider edge cases and error conditions
- Add accessibility tests where appropriate
118 changes: 118 additions & 0 deletions lib/galaxy_test/selenium/.claude/commands/extract-selenium-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
description: Extract test code from a Jupyter notebook and convert it to a proper Selenium test file
---

The user input can be provided directly or as a command argument - you **MUST** consider it before proceeding.

User input:

$ARGUMENTS

## Context

After prototyping a Selenium test interactively in a Jupyter notebook, this command extracts the test code and converts it into a proper test file following Galaxy's Selenium testing conventions.

## Task

Extract test cells from a Jupyter notebook and create a properly structured Selenium test file.

## Requirements

1. **Read the target notebook** specified by the user (e.g., `jupyter/test_prototype_<name>.ipynb`)

2. **Read CLAUDE.md** for full context on Galaxy Selenium test conventions

3. **Identify test cells** - Extract all cells after the initialization cell (cell 2):
- Skip the parameters cell (cell 0)
- Skip the initialization cell (cell 1)
- Extract cells 2+ which contain the test implementation

4. **Transform notebook code to test code**:
- Replace `gx_selenium_context.` with `self.`
- Remove screenshot calls or keep them if desired for debugging
- Group related operations into logical test methods
- Add proper decorators (`@selenium_test`, `@managed_history`, etc.)
- Add docstrings to test methods

5. **Determine test structure** from the notebook code:
- Does it need `ensure_registered = True`? (if it calls `register()` or `login()`)
- Does it need `run_as_admin = True`? (if it calls `admin_login()`)
- Does it need `@managed_history`? (if it works with datasets/HIDs)
- Does it need `@requires_admin`? (if testing admin features)

6. **Create proper test file**:
- Add appropriate imports
- Create test class with correct name
- Add class attributes as needed
- Create test methods from notebook cells
- Group related cells into single test methods
- Split unrelated operations into separate test methods

7. **Handle special cases**:
- If notebook uses `dataset_populator`, keep those patterns
- If notebook uses `current_history_id()`, consider `@managed_history`
- If notebook has multiple distinct scenarios, create multiple test methods
- Convert inline assertions to proper pytest assertions

8. **File naming**: Ask user for feature name if not clear from notebook name

## Output

1. **Analyze the notebook** and report:
- Number of test cells found
- Key operations detected (login, upload, navigation, etc.)
- Recommended test structure (basic/managed history/admin)

2. **Ask for confirmation** if structure is ambiguous:
- Should this be one test method or multiple?
- What should the test methods be named?
- Should screenshots be kept or removed?

3. **Create the test file** at `test_<feature_name>.py` with:
- Proper imports
- Correctly structured test class
- Appropriate decorators and attributes
- Well-named test methods with docstrings
- Transformed code (gx_selenium_context → self)

4. **Report completion**:
```
✓ Extracted test from notebook: jupyter/test_prototype_<name>.ipynb
✓ Created test file: test_<feature_name>.py

Test structure:
- Class: Test<FeatureName>
- Attributes: [ensure_registered, run_as_admin, etc.]
- Methods: test_method_1, test_method_2, ...

To run the test:
pytest lib/galaxy_test/selenium/test_<feature_name>.py

Or run a specific test:
pytest lib/galaxy_test/selenium/test_<feature_name>.py::Test<FeatureName>::test_method_1
```

5. **Provide review guidance**:
- Suggest reviewing for proper wait/sleep patterns
- Recommend adding assertions if few were found
- Suggest accessibility testing if not present
- Note any hardcoded values that should be parameterized

## Example Usage

```
/extract-test from jupyter/test_prototype_dataset_metadata.ipynb
/extract-test jupyter/test_prototype_workflow_import.ipynb as test_workflow_import
/extract-test notebook test_prototype_admin_users.ipynb
```

## Notes

- Read CLAUDE.md for complete context on test conventions
- The notebook's initialization cells (0-1) are never included in the test
- Multiple notebook cells can be combined into a single test method if related
- Distinct scenarios should become separate test methods
- The command should intelligently detect patterns (admin, managed history, etc.)
- Preserve the logic but adapt to test framework conventions
- Remove debug-only code (print statements, excessive screenshots)
- Keep test-relevant screenshots if they help document expected states
Loading
Loading