Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1424f3a
Add initial admin_responses command
nickmoreton Jan 30, 2024
509d125
Remove the old _base_admin_responses
nickmoreton Jan 30, 2024
1a2f024
Update admin_responses docs
nickmoreton Jan 30, 2024
804ce1a
Remove some testing data
nickmoreton Jan 31, 2024
f3abac8
Correct test after update
nickmoreton Jan 31, 2024
a328811
Deal with alternate sites for frontend urls
nickmoreton Feb 3, 2024
bf5b2b2
Outputs both sites as alternative API views
nickmoreton Feb 3, 2024
45ab7f7
Add playwright to the dev dependencies
nickmoreton Feb 3, 2024
3984c6d
Initial playwright command
nickmoreton Feb 4, 2024
6b88a12
Merge pull request #26 from wagtail-packages/try-playwright
nickmoreton Feb 4, 2024
a429e18
Optimize the `cmd_playwright_responses` command a little
nickmoreton Feb 4, 2024
18e72ad
Add more command options to the playwright test command
nickmoreton Feb 4, 2024
e8e5109
Better console output for playwright responses
nickmoreton Feb 4, 2024
72efe52
Output a summary_report
nickmoreton Feb 4, 2024
3f2a2f2
Add better reporting for playwright responses
nickmoreton Feb 4, 2024
7f90b92
Remove un-needed print statement
nickmoreton Feb 4, 2024
867c4f9
Fix failing tests
nickmoreton Feb 4, 2024
3115465
update the check_responses command
nickmoreton Feb 4, 2024
02f8e8f
save 25-separate-frontend-and-backend-api-views.patch
nickmoreton Feb 4, 2024
790dcd7
Sort by groups for the API view
nickmoreton Feb 5, 2024
4cf81a9
Signal when authenticated
nickmoreton Feb 5, 2024
65e35e3
Better group names
nickmoreton Feb 5, 2024
ce8c199
Provide expanded switcher
nickmoreton Feb 5, 2024
dd7e7fd
Mask redundant tests for now.
nickmoreton Feb 5, 2024
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
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ A set of developer tools in the form of management commands.

### API

There is an api now available at `/wagtail-devtools-api/` which will list all available commands.
There is an api available at `/wagtail-devtools-api/` which will list all available endpoints.

- List all editor listing pages
- List all editor edit pages

### Admin Responses

The `admin_responses` command will make a requests to the admin interface using get requests for a range of models. It will write a response result to the console.
The `admin_responses` command will use the API endpoints above to create a report of error and success pages in the console.

- [Documentation](docs/admin_responses.md)

Expand Down
186 changes: 32 additions & 154 deletions docs/admin_responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,172 +4,50 @@ The `admin_responses` command will make a requests to the admin interface using

**Note:** As the command makes requests to the admin interface it will need a local development site to be running in `DEBUG` mode. It will work best if you have a full set of test data for all models.

Reports can be generated for:
Reports are generated for:

- Admin Listing and Edit pages
- Frontend Pages

You can also add admin reports covering:

- Snippets
- Settings
- ModelAdmin
- Pages
- and more...

## Usage

Create a command class in your app's `management/commands` directory thats inherits from `BaseAdminResponsesCommand` with the following content:

```python
from wagtail_devtools.management.commands._base_admin_responses import (
BaseAdminResponsesCommand,
)


class Command(BaseAdminResponsesCommand):
def get_reports(self, *args, **options):
session = self._log_in(options)

register_reports = [
# Add your reports here
]
```

You can use any name for the command file, but it must be in a `management/commands` directory.

I'll use `report_responses.py` as an example.

**Note:** A full command that uses all available checks can be found in the [cmd_test_admin_responses.py](../wagtail_devtools/test/management/commands/cmd_test_admin_responses.py) file which you can use as a quick start.

### Page Models Report

Will generate a report for all admin edit pages for all page type models and corresponding frontend pages.

It does this by automatically finding all page models, then using a get request it will check the response status code for the admin edit page and the frontend page.

#### Setup

Add the following item to the `register_reports` list:

```python
{
"function": self.report_pages,
"args": [session, options],
}
```bash
python manage.py admin_responses
```

- `function` is the function that will be called to generate the report.
- `args` is a list of arguments that will need to be passed to the function.
- `session` is the session object that will be used to make the requests.
- `options` is the commands options object that is passed to the command.

#### Example Console Output
### Example Console Output

![Page Model Report](./assets/pages-output.jpg)

If your terminal allows it the links should be clickable.

Any pages that return a response code other than 200 will be highlighted in red.

### Admin Listing Pages Report

Will generate a report for all admin listing pages.

```python
{
"function": self.report_admin_list_pages,
"args": [
session,
"Dashboard",
f"{options['host']}{reverse('wagtailadmin_home')}",
],
}
```

It does this by making a get request to the specified admin listing page and checking the response status code.

- `function` is the function that will be called to generate the report.
- `args` is a list of arguments that will need to be passed to the function.
- `session` is the session object that will be used to make the requests.
- `Dashboard` is the title of the report.
- `f"{options['host']}{reverse('wagtailadmin_home')}"` is the url of the admin listing page to check.

#### Other admin listing page reports

You can also generate reports for other admin listing pages. Use the following wagtail urls as the third argument and a title of the report as the second argument:

- Aging Pages: `f"{options['host']}{reverse('wagtailadmin_reports:aging_pages')}"`
- Collections: `f"{options['host']}{reverse('wagtailadmin_collections:index')}"`
- Dashboard: `f"{options['host']}{reverse('wagtailadmin_home')}"`
- Documents: `f"{options['host']}{reverse('wagtaildocs:index')}"`
- Groups: `f"{options['host']}{reverse('wagtailusers_groups:index')}"`
- Images: `f"{options['host']}{reverse('wagtailimages:index')}"`
- Locked Pages: `f"{options['host']}{reverse('wagtailadmin_reports:locked_pages')}"`
- Redirects: `f"{options['host']}{reverse('wagtailredirects:index')}"`
- Search: `f"{options['host']}{reverse('wagtailadmin_explore_root')}"`
- Site History: `f"{options['host']}{reverse('wagtailadmin_reports:site_history')}"`
- Sites: `f"{options['host']}{reverse('wagtailsites:index')}"`
- Snippets: `f"{options['host']}{reverse('wagtailsnippets:index')}"`
- Users: `f"{options['host']}{reverse('wagtailusers_users:index')}"`
- Workflow List: `f"{options['host']}{reverse('wagtailadmin_workflows:index')}"`
- Workflow Tasks: `f"{options['host']}{reverse('wagtailadmin_workflows:task_index')}"`

### Admin Model Edit Pages Report

Will generate a report for the admin edit page using the specified app and model.

It does this by making a get request to the corresponding admin edit page for the model and checking the response status code.

```python
{
"function": self.report_admin_app_model,
"args": [
session,
options,
"WORKFLOWS EDIT",
"wagtailcore",
"Workflow",
],
},
```

- `function` is the function that will be called to generate the report.
- `args` is a list of arguments that will need to be passed to the function.
- `session` is the session object that will be used to make the requests.
- `options` is the commands options object that is passed to the command.
- `WORKFLOWS EDIT` is the title of the report.
- `wagtailcore` is the app name.
- `Workflow` is the model name.

#### Other admin app.model reports

You can also generate reports for edit pages for other models:

- Documents: `report_documents`
- Images: `report_images`
- Users: `report_users`
- Groups: `report_groups`
- Sites: `report_sites`
- Collections: `report_collections`
- Snippets: `report_snippets`


### ModelAdmin Reports

Will generate a report for the admin edit page using the specified modeladmin models.

It does this by making a get request to the corresponding admin edit page for the model and checking the response status code.

```python
{
"function": self.report_model_admin,
"args": [session, options, ["app.Model"]],
}
```

- `function` is the function that will be called to generate the report.
- `args` is a list of arguments that will need to be passed to the function.
- `session` is the session object that will be used to make the requests.
- `options` is the commands options object that is passed to the command.
- `["app.Model"]` is a list of registered modeladmin app.model strings.
#### Listing Page Checks

- Aging Pages: `wagtailadmin_reports:aging_pages`
- Collections: `wagtailadmin_collections:index`
- Dashboard: `wagtailadmin_home`
- Documents: `wagtaildocs:index`
- Groups: `wagtailusers_groups:index`
- Images: `wagtailimages:index`
- Locked Pages: `wagtailadmin_reports:locked_pages`
- Redirects: `wagtailredirects:index`
- Search: `wagtailadmin_explore_root`
- Site History: `wagtailadmin_reports:site_history`
- Sites: `wagtailsites:index`
- Snippets: `wagtailsnippets:index`
- Users: `wagtailusers_users:index`
- Workflow List: `wagtailadmin_workflows:index`
- Workflow Tasks: `wagtailadmin_workflows:task_index`

### Edit Page Checks

- Documents
- Images
- Users
- Groups
- Sites
- Collections
- Snippets
- ModelAdmin Models
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ dev = [
"flake8==6.1.0",
"isort==5.12.0",
"coverage==7.3.2",
"playwright==1.41.1",
]

[project.urls]
Expand Down
10 changes: 0 additions & 10 deletions wagtail_devtools/api/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,6 @@
"app_name": None,
"listing_name": "wagtailusers_groups:index",
},
{
"title": "Example Calendar (admin view)",
"app_name": None,
"listing_name": "calendar",
},
{
"title": "Example Calendar (admin view - month)",
"app_name": None,
"listing_name": "calendar-month",
},
]


Expand Down
13 changes: 13 additions & 0 deletions wagtail_devtools/api/dataclasses.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from dataclasses import dataclass, field
from urllib.parse import urlparse

from django.conf import settings
from django.urls import reverse
from wagtail.models import Site

from wagtail_devtools.api.helpers import get_admin_edit_url, get_host

Expand Down Expand Up @@ -39,6 +41,17 @@ def _editor_url(self):

@property
def _url(self):
current_site = Site.find_for_request(self.request)
hostname = current_site.hostname if current_site else None

url_parsed = urlparse(
self.item.get_url() if hasattr(self.item, "get_url") else None
)
netloc = url_parsed.netloc if url_parsed else None

if netloc and not netloc.startswith(hostname):
return None

return self.item.get_url() if hasattr(self.item, "get_url") else None

def get(self):
Expand Down
49 changes: 27 additions & 22 deletions wagtail_devtools/api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.apps import apps
from wagtail.admin.admin_url_finder import AdminURLFinder
from wagtail.models.collections import Collection
from wagtail.snippets.models import get_snippet_models

from wagtail_devtools.api.dataclasses import (
Expand Down Expand Up @@ -30,31 +29,37 @@ def wagtail_core_apps_serializer(request, config, title, all=False):

results = Results()

"""
Loop though all the apps and models and get the first item for each model
But pages need to be children of the current site
"""

for app in config["apps"]:
models = apps.get_app_config(app["app_name"]).get_models()
if not all:
for model in models:
item = model.objects.first()
if isinstance(item, Collection):
item = Collection.objects.first().get_first_child()
for model in models:
is_collection = model.__name__ == "Collection"
is_snippet = model.__name__ in [
model.__name__ for model in get_snippet_models()
]

if is_collection:
items = (
# don't include the root collection
[model.objects.first().get_first_child()]
if not all
else model.objects.all().exclude(depth=1)
)

if is_snippet:
items = [model.objects.first()] if not all else model.objects.all()

if not is_collection and not is_snippet:
# must be some other model that doesn't need special handling
items = [model.objects.first()] if not all else model.objects.all()

for item in items:
if AdminURLFinder().get_edit_url(item):
results.add(ResultsModelItem(request, item).get())
else:
for model in models:
items = model.objects.all()
if isinstance(items.first(), Collection):
for item in items:
# if AdminURLFinder().get_edit_url(item): # TODO decide if this is required, do some testing on real data
results.add(ResultsModelItem(request, item).get())
snippet_models = [model.__name__ for model in get_snippet_models()]
if model.__name__ in snippet_models:
for item in items:
# if AdminURLFinder().get_edit_url(item): # TODO decide if this is required, do some testing on real data
results.add(ResultsModelItem(request, item).get())
else:
for item in items:
if AdminURLFinder().get_edit_url(item):
results.add(ResultsModelItem(request, item).get())

ret["results"] = results.get()

Expand Down
10 changes: 6 additions & 4 deletions wagtail_devtools/api/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from django.urls import path

from .views import api_view, wagtail_core_apps, wagtail_core_listing_pages
from .views import ( # api_view,; wagtail_core_apps,; wagtail_core_listing_pages,
responses_api_view,
)


urlpatterns = [
path("", api_view, name="api_index"),
path("listing-types/", wagtail_core_listing_pages, name="listing-types"),
path("wagtail-core-apps/", wagtail_core_apps, name="wagtail-core-apps"),
path("", responses_api_view, name="responses_api_view"),
# path("listing-types/", wagtail_core_listing_pages, name="listing-types"),
# path("wagtail-core-apps/", wagtail_core_apps, name="wagtail-core-apps"),
]
Loading