Fix HTML datasets with extra files returning 404 errors when previewed.
Without a trailing slash on the display URL, the browser resolves
relative paths (e.g., image.jpg) against /datasets/{id}/ instead of
/datasets/{id}/display/, causing sub-resources to fail loading.
Adds a playwright test that verifies the trailing slash is present in
the iframe src and that extra files are accessible via relative paths.
https://claude.ai/code/session_01AvNoEjTngF3u59NJvSmPrg
When a workflow step parameter references a deleted dataset,
compute_runtime_state() previously discarded validation errors,
allowing a raw dict to flow into process_dataset() and crash with
AttributeError: 'dict' object has no attribute 'find_conversion_destination'.
- Handle step_errors in ToolModule.execute() instead of discarding them
- Pass simple_errors=False so check_param preserves ParameterValueError
objects with the resolved model instance as parameter_value
- Pass the deleted HDA/HDCA as parameter_value in ParameterValueError
so callers can inspect it structurally instead of string-matching
- Add InvocationFailureStepInputDeleted schema type with hda_id/hdca_id
fields, falling back to InvocationFailureWorkflowParameterInvalid for
other validation errors
- Add frontend rendering for the new step_input_deleted reason
- Add deterministic API test using a pause step to control timing
Fixes#21969
The switch from srcdoc to iframe src (d3b31b0554) broke HTML datasets
that reference extra files via relative paths (JBrowse2, FastQC, etc).
Without a trailing slash on the display URL, the browser resolves
relative paths against /datasets/{id}/ instead of /datasets/{id}/display/,
so sub-resources like static/js/main.js hit routes that don't exist.
Adding the trailing slash fixes resolution and matches the existing
pattern in HistoryDatasetDisplay.vue.
Instead of converting NO_REPLACEMENT to None early (which overrides downstream
tool parameter defaults), handle it at the boundaries:
1. In replacement_for_connection: detect raw NoReplacement sentinel objects
stored in step outputs and return NO_REPLACEMENT, so the existing
visit_input_values logic correctly falls through to tool-level defaults.
2. In set_outputs_for_input: skip runtime_replacements when output is
NO_REPLACEMENT to prevent stringified sentinel in tool commands.
This preserves the semantic distinction between "not provided" (NO_REPLACEMENT)
and "explicitly null" (None), letting downstream steps use their own defaults
when an optional parameter is omitted.
The framework test uses a workflow with:
- A required data input (making inputs_by_step_id non-empty)
- An optional text parameter connected to a rename post-job action
- Verification that the output name matches the unexpanded template
and fails with without this fix
```
FAILED lib/galaxy_test/workflow/test_framework_workflows.py::TestWorkflow::test_workflow[optional_param_default_value_0] - Exception: Dataset metadata verification for [name] failed, expected [prefix_${optional_text}_suffix] but found [prefix_NO_REPLACEMENT singleton_suffix]
```
Addresses galaxyproject/galaxy#21947
Route framework workflow tests through galactic_job_json() (shared with
Planemo) instead of custom load_data_dict() dispatch. Detect class: syntax
in test YAML and route accordingly, preserving backward compat.
- Fix filetype not forwarded for contents uploads in galactic_job_json
- FileLiteralTarget reads filetype/dbkey from properties in staging
- Add _uses_class_syntax() detection + routing in run_workflow()
- Extract type: raw params before stage_inputs(), merge back after
- Thread name from YAML through CollectionCreateFunc protocol and staging
- Thread name for File inputs through replacement_file() to upload targets
- Fix path resolution in stage_inputs() using TestDataResolver fallback
- Pass use_path_paste=False from run_workflow() to avoid admin-only file:// URIs
- Convert ~20 gxwf-tests.yml files to class: Collection/File syntax with explicit elements
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 'tabs' class to outer container (BTabs rendered 'tabs b-tabs').
Use <a> instead of <button> for tab nav items — BTabs used anchor elements
and several Selenium tests select on 'a.nav-link'.
BOverlay uses scoped slots internally which crash under @vue/compat
with a renderSlot TypeError. GOverlay is a simple CSS overlay with a
spinner, covering the same API surface used across the codebase:
show prop, opacity, no-fade, and a custom #overlay slot.
Migrated all 5 files that used BOverlay: GTable, HistoryList,
WorkflowList, BroadcastsList, and WorkflowRunFormSimple.
The previous <component :is="() => vnodes" /> pattern is a Vue 3
functional component shorthand that Vue 2.7 silently ignores. Replace
it with a proper defineComponent using setup returning a render function,
which Vue 2.7 supports.
Use ref() instead of reactive() for the tabs array in GTabs to avoid
Vue 2.7 "Array as root value for reactive()" warning that triggers
vitest-fail-on-console. Update DatasetView and UploadModal tests to
stub GTabs/GTab instead of BTabs/BTab, and adjust DatasetAttributes
button counts to account for tab navigation buttons rendered by GTabs.
Add GTabs and GTab as Bootstrap-Vue-free tab components that use
provide/inject for parent-child communication and render functions
for title slot content. They support all the props used across the
codebase: v-model, justified, fill, pills, card, vertical, lazy,
title slots, and click events — all rendered with Bootstrap's
existing CSS classes so there's no visual change.
Migrated all 14 files that imported BTabs/BTab, including nested
tabs (SanitizeAllow), complex active-tab sync (UploadContainer),
and title slots with icons/badges.