An easy-to-use package for testing SEO. The package allows you to extract SEO tags from a given HTML and verify that the SEO structure is correct.
You can install the package via composer:
composer require juampi92/test-seo --dev
// Create TestSEO instance using the response:
$seo = new TestSEO($htmlResponse);
// Perform assertions:
$seo->assertTitleEndsWith(' - My Website');
// Assert the data yourself:
$this->assertEquals(
'My title - My Website',
$seo->data->title()
);
Look at the following examples using PHPUnit, Laravel, and Pest.
public function testLandingPageSEO()
{
// Arrange
// ...
// Act
$response = $client->get('/')->send();
// Assert
$this->assertEquals(200, $response->getStatusCode());
$html = json_decode($response->getBody(true), true);
$seo = new TestSEO($html);
// Assert
$seo
->assertTitleEndsWith(' - My Website')
->assertCanonicalIs('https://www.mywebsite.com/');
}
public function test_landing_page_SEO()
{
// Arrange
// ...
// Act
$response = $this->get('/');
// Assert
$response->assertStatus(200);
$seo = new TestSEO($response->getContent());
$seo
->assertTitleEndsWith(' - My Website')
->assertCanonicalIs('https://www.mywebsite.com/');
}
test('landing page SEO tags', function () {
// Arrange
// ...
// Act
$response = get('/')->assertStatus(200);
$seo = new TestSEO($response->getContent());
// Assert
expect($seo->data)
->title()->toEndWith(' - My Website')
->description()->toBe('This is my description')
->canonical()->not()->toBeNull()
->robots()->index()->toBeTrue()
->robots()->nofollow()->toBeTrue();
});
You can access the SEO Data yourself by accessing the public property TestSEO->data
.
Here are the available methods:
Method | Returns | Description |
---|---|---|
title() |
?string |
<title>{this}</title> |
description() |
?string |
<meta name="description" content="{this}"> |
image() |
?Url 🔍 |
<meta name="image" content="{this}"> |
robots() |
Robots 🔍 |
<meta name="robots" content="{this}"> |
canonical() |
?Url 🔍 |
<link rel="canonical" href="{this}"> |
prev() |
?Url 🔍 |
<link rel="prev" href="{this}"> |
next() |
?Url 🔍 |
<link rel="next" href="{this}"> |
openGraph() |
TagCollection 🔍 |
<meta property="og:{key}" content="{value}"> |
twitter() |
TagCollection 🔍 |
<meta name="twitter:{key}" content="{value}"> |
alternateHrefLang() |
AlternateHrefLangCollection 🔍 |
<link name="alternate" hreflang="{hreflang}" href={href}> |
images() |
array<array{src: string, alt: string, title: string}> |
All images in the page. <img src="..."> |
h1s() |
array<string> |
All H1 in the page. <h1>{this}</h1> |
h2s() |
array<string> |
All H2 in the page. <h2>{this}</h2> |
charset() |
?string |
<meta charset="utf-8"> |
The SEOData class is Macroable, so feel free to extend it yourself.
Method | Notes |
---|---|
assertCanonicalIs(string $expected) |
|
assertCanonicalIsEmpty() |
|
assertRobotsIsEmpty() |
|
assertRobotsIsNoIndexNoFollow() |
Checks that the robots are noindex, nofollo or none |
assertPaginationIsEmpty() |
prev and next are both missing. |
assertAlternateHrefLangIsEmpty() |
|
assertTitleIs(string $expected) |
|
assertTitleContains(string $expected) |
|
assertTitleEndsWith(string $expected) |
|
assertDescriptionIs(string $expected) |
|
assertThereIsOnlyOneH1() |
Make sure there is only one H1 in the entire website. |
assertAllImagesHaveAltText() |
Make sure all images have an alt="..." |
Suggest your own! | These assertions can help devs to follow the best SEO practices. Make a PR if you think some are missing! |
When it comes to SEO, a snapshot test is a great way to ensure nothing has been changed by accident.
Here is an example:
$seo = new TestSEO($response->getContent(), snapshotSerializer: null);
$json = json_encode($seo);
By default, the SEO tags are serialized using the SimpleSerializer
.
Make your own serializer by implementing the SnapshotSerializer
interface:
$seo = new TestSEO($response->getContent(), new MyCustomSerializer());
$json = json_encode($seo);
use function Spatie\Snapshots\{assertMatchesSnapshot, assertMatchesJsonSnapshot};
use Juampi92\TestSEO\TestSEO;
test('landing page SEO', function () {
$response = $this->get('/');
$response->assertStatus(200);
$seo = new TestSEO($response->getContent());
assertMatchesJsonSnapshot(json_encode($seo));
});
Note: this example requires spatie/pest-plugin-snapshots
.
Please see CONTRIBUTING for details.
The MIT License (MIT). Please see License File for more information.