Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 5.2.9 on 2025-12-16 21:27

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('experiments', '0305_delete_jetstream_changelogs'),
]

operations = [
migrations.RemoveField(
model_name='nimbusexperiment',
name='qa_run_test_plan',
),
migrations.RemoveField(
model_name='nimbusexperiment',
name='qa_run_testrail_link',
),
migrations.AddField(
model_name='nimbusexperiment',
name='qa_run_test_plan_url',
field=models.URLField(blank=True, default=None, max_length=500, null=True, verbose_name='QA Run Test Plan URL'),
),
migrations.AddField(
model_name='nimbusexperiment',
name='qa_run_testrail_url',
field=models.URLField(blank=True, default=None, max_length=500, null=True, verbose_name='QA Run TestRail URL'),
),
]
8 changes: 4 additions & 4 deletions experimenter/experimenter/experiments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,15 +464,15 @@ class NimbusExperiment(NimbusConstants, TargetingConstants, FilterMixin, models.
)
tags = models.ManyToManyField(Tag, blank=True, related_name="experiments")
qa_run_date = models.DateField("QA Run Date", blank=True, null=True, default=None)
qa_run_test_plan = models.URLField(
"QA Run Test Plan Link",
qa_run_test_plan_url = models.URLField(
"QA Run Test Plan URL",
max_length=500,
blank=True,
null=True,
default=None,
)
qa_run_testrail_link = models.URLField(
"QA Run TestRail Link",
qa_run_testrail_url = models.URLField(
"QA Run TestRail URL",
max_length=500,
blank=True,
null=True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ def test_outputs_expected_schema_for_empty_experiment(self):
"qa_run_date": None,
"qa_signoff": False,
"qa_status": NimbusExperiment.QAStatus.NOT_SET,
"qa_run_test_plan": None,
"qa_run_testrail_link": None,
"qa_run_test_plan_url": None,
"qa_run_testrail_url": None,
"reference_branch": None,
"required_experiments": [],
"requires_restart": False,
Expand Down Expand Up @@ -231,8 +231,8 @@ def test_outputs_expected_schema_for_complete_experiment(self):
"qa_run_date": experiment.qa_run_date,
"qa_signoff": False,
"qa_status": experiment.qa_status,
"qa_run_test_plan": experiment.qa_run_test_plan,
"qa_run_testrail_link": experiment.qa_run_testrail_link,
"qa_run_test_plan_url": experiment.qa_run_test_plan_url,
"qa_run_testrail_url": experiment.qa_run_testrail_url,
"required_experiments": [],
"requires_restart": False,
"results_data": experiment.results_data,
Expand Down
16 changes: 8 additions & 8 deletions experimenter/experimenter/experiments/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4306,15 +4306,15 @@ def test_qa_run_date_accepts_valid_date(self):
experiment = NimbusExperimentFactory.create(qa_run_date=test_date)
self.assertEqual(experiment.qa_run_date, test_date)

def test_qa_run_test_plan_accepts_valid_url(self):
def test_qa_run_test_plan_url_accepts_valid_url(self):
test_url = "https://example.com/test-plan"
experiment = NimbusExperimentFactory.create(qa_run_test_plan=test_url)
self.assertEqual(experiment.qa_run_test_plan, test_url)
experiment = NimbusExperimentFactory.create(qa_run_test_plan_url=test_url)
self.assertEqual(experiment.qa_run_test_plan_url, test_url)

def test_qa_run_testrail_link_accepts_valid_url(self):
def test_qa_run_testrail_url_accepts_valid_url(self):
test_url = "https://testrail.example.com/index.php?/runs/view/12345"
experiment = NimbusExperimentFactory.create(qa_run_testrail_link=test_url)
self.assertEqual(experiment.qa_run_testrail_link, test_url)
experiment = NimbusExperimentFactory.create(qa_run_testrail_url=test_url)
self.assertEqual(experiment.qa_run_testrail_url, test_url)

def test_clone_created_experiment(self):
owner = UserFactory.create()
Expand Down Expand Up @@ -4466,8 +4466,8 @@ def _clone_experiment_and_assert_common_expectations(
self.assertEqual(child.qa_status, NimbusExperiment.QAStatus.NOT_SET)
self.assertEqual(child.qa_comment, None)
self.assertEqual(child.qa_run_date, None)
self.assertEqual(child.qa_run_test_plan, None)
self.assertEqual(child.qa_run_testrail_link, None)
self.assertEqual(child.qa_run_test_plan_url, None)
self.assertEqual(child.qa_run_testrail_url, None)
self.assertEqual(child._start_date, None)
self.assertEqual(child._end_date, None)
self.assertEqual(child._enrollment_end_date, None)
Expand Down
9 changes: 8 additions & 1 deletion experimenter/experimenter/nimbus_ui/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,16 @@ def get_changelog_message(self):
class QAStatusForm(NimbusChangeLogFormMixin, forms.ModelForm):
class Meta:
model = NimbusExperiment
fields = ["qa_status", "qa_comment"]
fields = [
"qa_status",
"qa_comment",
"qa_run_test_plan_url",
"qa_run_testrail_url",
]
widgets = {
"qa_status": forms.Select(choices=NimbusExperiment.QAStatus),
"qa_run_test_plan_url": forms.URLInput(attrs={"class": "form-control"}),
"qa_run_testrail_url": forms.URLInput(attrs={"class": "form-control"}),
}

def __init__(self, *args, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,15 +247,15 @@ <h5 class="fw-semibold mt-3 d-flex align-items-center">
</div>
</td>
<td id="qa-test-plan">
{% if experiment.qa_run_test_plan %}
<a href="{{ experiment.qa_run_test_plan }}">Test Plan Link</a>
{% if experiment.qa_run_test_plan_url %}
<a href="{{ experiment.qa_run_test_plan_url }}">Test Plan URL</a>
{% else %}
<span class="text-danger">Not set</span>
{% endif %}
</td>
<td id="qa-testrail-link" class="col-2">
{% if experiment.qa_run_testrail_link %}
<a href="{{ experiment.qa_run_testrail_link }}">TestRail Link</a>
{% if experiment.qa_run_testrail_url %}
<a href="{{ experiment.qa_run_testrail_url }}">TestRail URL</a>
{% else %}
<span class="text-danger">Not set</span>
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{% load nimbus_extras %}

<table class="table table-striped">
<tbody>
<tr>
Expand All @@ -8,5 +10,29 @@
<th>QA Comment</th>
<td colspan="3">{{ experiment.qa_comment|default:"No comment" }}</td>
</tr>
<tr>
<th>Test Scenarios/Suites URL</th>
<td colspan="3">
{% if experiment.qa_run_test_plan_url %}
<a href="{{ experiment.qa_run_test_plan_url }}"
target="_blank"
rel="noopener noreferrer">{{ experiment.qa_run_test_plan_url }}</a>
{% else %}
{{ experiment.qa_run_test_plan_url|default:"Not provided" }}
{% endif %}
</td>
</tr>
<tr>
<th>TestRail Results URL</th>
<td colspan="3">
{% if experiment.qa_run_testrail_url %}
<a href="{{ experiment.qa_run_testrail_url }}"
target="_blank"
rel="noopener noreferrer">{{ experiment.qa_run_testrail_url }}</a>
{% else %}
{{ experiment.qa_run_testrail_url|default:"Not provided" }}
{% endif %}
</td>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@
<label for="id_qa_comment" class="col-sm-2 col-form-label">QA Comment:</label>
<div class="col-sm-10">{{ form.qa_comment }}</div>
</div>
<div class="mb-3 row">
<label for="id_qa_run_test_plan_url" class="col-sm-2 col-form-label">Test Scenarios/Suites URL:</label>
<div class="col-sm-10">
{{ form.qa_run_test_plan_url }}
{% for error in form.qa_run_test_plan_url.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
</div>
</div>
<div class="mb-3 row">
<label for="id_qa_run_testrail_url" class="col-sm-2 col-form-label">TestRail Results URL:</label>
<div class="col-sm-10">
{{ form.qa_run_testrail_url }}
{% for error in form.qa_run_testrail_url.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
</div>
</div>
<div class="d-flex justify-content-end mt-3">
<button type="submit" class="btn btn-primary me-2">Save</button>
<button type="button"
Expand Down
43 changes: 43 additions & 0 deletions experimenter/experimenter/nimbus_ui/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ def test_form_updates_qa_fields_and_creates_changelog(self):
data = {
"qa_status": NimbusExperiment.QAStatus.GREEN,
"qa_comment": "tests passed",
"qa_run_test_plan_url": "",
"qa_run_testrail_url": "",
}
form = QAStatusForm(data, request=self.request, instance=experiment)
self.assertTrue(form.is_valid(), form.errors)
Expand All @@ -440,6 +442,8 @@ def test_form_updates_qa_run_date_when_status_changes(self):
data = {
"qa_status": NimbusExperiment.QAStatus.GREEN,
"qa_comment": "tests passed",
"qa_run_test_plan_url": "",
"qa_run_testrail_url": "",
}
form = QAStatusForm(data, request=self.request, instance=experiment)
self.assertTrue(form.is_valid(), form.errors)
Expand All @@ -459,6 +463,8 @@ def test_form_updates_qa_run_date_only_when_status_changes(self):
data = {
"qa_status": NimbusExperiment.QAStatus.GREEN,
"qa_comment": "updated comment",
"qa_run_test_plan_url": "",
"qa_run_testrail_url": "",
}
form = QAStatusForm(data, request=self.request, instance=experiment)
self.assertTrue(form.is_valid(), form.errors)
Expand All @@ -477,6 +483,8 @@ def test_form_updates_qa_run_date_when_status_changes_from_one_to_another(self):
data = {
"qa_status": NimbusExperiment.QAStatus.GREEN,
"qa_comment": "retested and passed",
"qa_run_test_plan_url": "",
"qa_run_testrail_url": "",
}
form = QAStatusForm(data, request=self.request, instance=experiment)
self.assertTrue(form.is_valid(), form.errors)
Expand All @@ -497,6 +505,8 @@ def test_form_does_not_update_qa_run_date_when_changing_to_not_set(self):
data = {
"qa_status": NimbusExperiment.QAStatus.NOT_SET,
"qa_comment": "resetting status",
"qa_run_test_plan_url": "",
"qa_run_testrail_url": "",
}
form = QAStatusForm(data, request=self.request, instance=experiment)
self.assertTrue(form.is_valid(), form.errors)
Expand All @@ -505,6 +515,39 @@ def test_form_does_not_update_qa_run_date_when_changing_to_not_set(self):
self.assertEqual(experiment.qa_status, NimbusExperiment.QAStatus.NOT_SET)
self.assertEqual(experiment.qa_run_date, old_date)

def test_form_updates_qa_url_fields(self):
experiment = NimbusExperimentFactory.create_with_lifecycle(
NimbusExperimentFactory.Lifecycles.CREATED,
qa_status=NimbusExperiment.QAStatus.NOT_SET,
qa_run_test_plan_url="",
qa_run_testrail_url="",
)
existing_changes = list(experiment.changes.values_list("id", flat=True))
data = {
"qa_status": NimbusExperiment.QAStatus.GREEN,
"qa_comment": "tests passed",
"qa_run_test_plan_url": "https://example.com/test-plan",
"qa_run_testrail_url": "https://testrail.example.com/results",
}
form = QAStatusForm(data, request=self.request, instance=experiment)
self.assertTrue(form.is_valid(), form.errors)

experiment = form.save()
self.assertEqual(experiment.qa_status, NimbusExperiment.QAStatus.GREEN)
self.assertEqual(experiment.qa_comment, "tests passed")
self.assertEqual(experiment.qa_run_test_plan_url, "https://example.com/test-plan")
self.assertEqual(
experiment.qa_run_testrail_url, "https://testrail.example.com/results"
)

self.assertEqual(experiment.changes.count(), 2)
changelog = experiment.changes.exclude(id__in=existing_changes).get()
self.assertEqual(changelog.changed_by, self.user)
self.assertEqual(
changelog.message,
"dev@example.com updated QA",
)


class TestTakeawaysForm(RequestFormTestCase):
def test_form_updates_takeaways_fields_and_creates_changelog(self):
Expand Down