Skip to content

Commit 7bd07be

Browse files
authored
Merge pull request #2 from RaiolaNetworks/devel
Initial release (#1)
2 parents 60cc34e + 489b970 commit 7bd07be

20 files changed

+249
-192
lines changed

README.md

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
# Test SEO
1+
# Plugin SEO Test
22

3-
[![Latest Version on Packagist](https://img.shields.io/packagist/v/juampi92/test-seo.svg?style=flat-square)](https://packagist.org/packages/juampi92/test-seo)
4-
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/juampi92/test-seo/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/juampi92/test-seo/actions?query=workflow%3Arun-tests+branch%3Amain)
5-
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/juampi92/test-seo/pint.yml?branch=main&label=code-style&style=flat-square)](https://github.com/juampi92/test-seo/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
6-
[![Total Downloads](https://img.shields.io/packagist/dt/juampi92/test-seo.svg?style=flat-square)](https://packagist.org/packages/juampi92/test-seo)
3+
[![Latest Version on Packagist](https://img.shields.io/packagist/v/raiolanetworks/plugin-seo-test.svg?style=flat-square)](https://packagist.org/packages/raiolanetworks/plugin-seo-test)
4+
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/raiolanetworks/plugin-seo-test/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/raiolanetworks/plugin-seo-test/actions?query=workflow%3Arun-tests+branch%3Amain)
5+
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/raiolanetworks/plugin-seo-test/pint.yml?branch=main&label=code-style&style=flat-square)](https://github.com/raiolanetworks/plugin-seo-test/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
6+
[![Total Downloads](https://img.shields.io/packagist/dt/raiolanetworks/plugin-seo-test.svg?style=flat-square)](https://packagist.org/packages/raiolanetworks/plugin-seo-test)
77

8-
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.
8+
This Composer package provides a seamless integration for testing SEO aspects of your Laravel applications.
9+
Compatible with both Pest and PHPUnit, it offers a collection of tools and assertions specifically designed to evaluate on-page SEO elements like meta tags, title tags, canonical URLs, and structured data.
10+
By automating SEO testing, this plugin ensures that your application consistently adheres to best SEO practices, helping you catch potential SEO issues early in the development cycle.
11+
12+
13+
## Get to know us
14+
15+
[<img src="https://cdn-assets.raiolanetworks.com/dist/images/logos/logo-blue.svg" width="419px" />](https://raiolanetworks.com)
16+
17+
18+
## Installation
919

1020
- [Installation](#instalation)
1121
- [Usage](#usage)
@@ -23,7 +33,7 @@ An easy-to-use package for testing SEO. The package allows you to extract SEO ta
2333
You can install the package via composer:
2434

2535
```bash
26-
composer require juampi92/test-seo --dev
36+
composer require raiolanetworks/plugin-seo-test --dev
2737
```
2838

2939
## Usage
@@ -51,7 +61,7 @@ public function testLandingPageSEO()
5161
{
5262
// Arrange
5363
// ...
54-
64+
5565
// Act
5666
$response = $client->get('/')->send();
5767

@@ -60,7 +70,7 @@ public function testLandingPageSEO()
6070
$html = json_decode($response->getBody(true), true);
6171

6272
$seo = new TestSEO($html);
63-
73+
6474
// Assert
6575
$seo
6676
->assertTitleEndsWith(' - My Website')
@@ -75,15 +85,15 @@ public function test_landing_page_SEO()
7585
{
7686
// Arrange
7787
// ...
78-
88+
7989
// Act
8090
$response = $this->get('/');
8191

8292
// Assert
8393
$response->assertStatus(200);
8494

8595
$seo = new TestSEO($response->getContent());
86-
96+
8797
$seo
8898
->assertTitleEndsWith(' - My Website')
8999
->assertCanonicalIs('https://www.mywebsite.com/');
@@ -96,12 +106,12 @@ public function test_landing_page_SEO()
96106
test('landing page SEO tags', function () {
97107
// Arrange
98108
// ...
99-
109+
100110
// Act
101111
$response = get('/')->assertStatus(200);
102-
112+
103113
$seo = new TestSEO($response->getContent());
104-
114+
105115
// Assert
106116
expect($seo->data)
107117
->title()->toEndWith(' - My Website')
@@ -122,19 +132,19 @@ Here are the available methods:
122132
| `title()` | `?string` | `<title>{this}</title>` |
123133
| `description()` | `?string` | `<meta name="description" content="{this}">` |
124134
| `image()` | `?Url` [🔍](https://github.com/spatie/url) | `<meta name="image" content="{this}">` |
125-
| `robots()` | `Robots` [🔍](https://github.com/juampi92/test-seo/blob/main/src/Tags/Robots.php) | `<meta name="robots" content="{this}">` |
135+
| `robots()` | `Robots` [🔍](https://github.com/raiolanetworks/plugin-seo-test/blob/main/src/Tags/Robots.php) | `<meta name="robots" content="{this}">` |
126136
| `canonical()` | `?Url` [🔍](https://github.com/spatie/url) | `<link rel="canonical" href="{this}">` |
127137
| `prev()` | `?Url` [🔍](https://github.com/spatie/url) | `<link rel="prev" href="{this}">` |
128138
| `next()` | `?Url` [🔍](https://github.com/spatie/url) | `<link rel="next" href="{this}">` |
129-
| `openGraph()` | `TagCollection` [🔍](https://github.com/juampi92/test-seo/blob/main/src/Tags/TagCollection.php) | `<meta property="og:{key}" content="{value}">` |
130-
| `twitter()` | `TagCollection` [🔍](https://github.com/juampi92/test-seo/blob/main/src/Tags/TagCollection.php) | `<meta name="twitter:{key}" content="{value}">` |
131-
| `alternateHrefLang()` | `AlternateHrefLangCollection` [🔍](https://github.com/juampi92/test-seo/blob/main/src/Tags/AlternateHrefLangCollection.php) | `<link name="alternate" hreflang="{hreflang}" href={href}>` |
139+
| `openGraph()` | `TagCollection` [🔍](https://github.com/raiolanetworks/plugin-seo-test/blob/main/src/Tags/TagCollection.php) | `<meta property="og:{key}" content="{value}">` |
140+
| `twitter()` | `TagCollection` [🔍](https://github.com/raiolanetworks/plugin-seo-test/blob/main/src/Tags/TagCollection.php) | `<meta name="twitter:{key}" content="{value}">` |
141+
| `alternateHrefLang()` | `AlternateHrefLangCollection` [🔍](https://github.com/raiolanetworks/plugin-seo-test/blob/main/src/Tags/AlternateHrefLangCollection.php) | `<link name="alternate" hreflang="{hreflang}" href={href}>` |
132142
| `images()` | `array<array{src: string, alt: string, title: string}>` | All images in the page. `<img src="...">` |
133143
| `h1s()` | `array<string>` | All H1 in the page. `<h1>{this}</h1>` |
134144
| `h2s()` | `array<string>` | All H2 in the page. `<h2>{this}</h2>` |
135145
| `charset()` | `?string` | `<meta charset="utf-8">` |
136146

137-
The SEOData class is **Macroable**, so feel free to extend it yourself.
147+
The SEOData class is **Macroable**, so feel free to extend it yourself.
138148

139149
## Assertions
140150

@@ -179,7 +189,7 @@ $json = json_encode($seo);
179189

180190
```php
181191
use function Spatie\Snapshots\{assertMatchesSnapshot, assertMatchesJsonSnapshot};
182-
use Juampi92\TestSEO\TestSEO;
192+
use Raiolanetworks\PluginSEOTest\TestSEO;
183193

184194
test('landing page SEO', function () {
185195
$response = $this->get('/');
@@ -200,8 +210,12 @@ Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
200210

201211
## Credits
202212

203-
- [Juan Pablo Barreto](https://github.com/juampi92)
204-
- [All Contributors](../../contributors)
213+
- [Martín Gómez](https://github.com/soymgomez)
214+
- [David Eguiluz](https://github.com/eguiluz)
215+
216+
## Credits to the original project
217+
218+
- [https://github.com/juampi92](https://github.com/juampi92/test-seo)
205219

206220
## License
207221

composer.json

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,62 @@
11
{
2-
"name": "juampi92/test-seo",
3-
"description": "Easy way to test your SEO",
4-
"keywords": [
5-
"phpunit",
6-
"php",
7-
"testing",
8-
"SEO"
9-
],
10-
"homepage": "https://github.com/juampi92/test-seo",
11-
"license": "MIT",
12-
"authors": [
13-
{
14-
"name": "Juan Pablo Barreto",
15-
"email": "[email protected]",
16-
"role": "Developer"
17-
}
18-
],
19-
"require": {
20-
"php": "^8.0.2",
21-
"illuminate/macroable": "^7.0|^8.0|^9.0|^10.0",
22-
"phpunit/phpunit": "^8.3|^9.0|^10.0",
23-
"spatie/url": "^1.3.4|^2.0",
24-
"symfony/dom-crawler": "^5.4|^6.1"
25-
},
26-
"require-dev": {
27-
"laravel/pint": "^1.0",
28-
"phpstan/phpstan": "^1.8"
29-
},
30-
"autoload": {
31-
"psr-4": {
32-
"Juampi92\\TestSEO\\": "src"
33-
}
34-
},
35-
"autoload-dev": {
36-
"psr-4": {
37-
"Juampi92\\TestSEO\\Tests\\": "tests"
38-
}
39-
},
40-
"scripts": {
41-
"analyse": "vendor/bin/phpstan analyse -c phpstan.neon.dist",
42-
"test": "vendor/bin/phpunit",
43-
"test-coverage": "vendor/bin/phpunit --coverage",
44-
"format": "vendor/bin/pint"
45-
},
46-
"config": {
47-
"sort-packages": true
48-
},
49-
"minimum-stability": "dev",
50-
"prefer-stable": true
2+
"name": "raiolanetworks/plugin-seo-test",
3+
"description": "This Composer package provides a seamless integration for testing SEO aspects of your Laravel applications. Compatible with both Pest and PHPUnit, it offers a collection of tools and assertions specifically designed to evaluate on-page SEO elements like meta tags, title tags, canonical URLs, and structured data. By automating SEO testing, this plugin ensures that your application consistently adheres to best SEO practices, helping you catch potential SEO issues early in the development cycle.",
4+
"keywords": [
5+
"Laravel",
6+
"PHPUnit",
7+
"PHP",
8+
"SEO",
9+
"Testing"
10+
],
11+
"homepage": "https://github.com/RaiolaNetworks/plugin-seo-test",
12+
"license": "MIT",
13+
"authors": [
14+
{
15+
"name": "Martín Gómez",
16+
"email": "[email protected]",
17+
"homepage": "https://raiolanetworks.com",
18+
"role": "Developer"
19+
},
20+
{
21+
"name": "David Eguiluz",
22+
"email": "[email protected]",
23+
"homepage": "https://raiolanetworks.com",
24+
"role": "Developer"
25+
}
26+
],
27+
"require": {
28+
"php": "^8.0.2",
29+
"illuminate/macroable": "^7.0|^8.0|^9.0|^10.0|^11.0",
30+
"phpunit/phpunit": "^8.3|^9.0|^10.0",
31+
"spatie/url": "^1.3.4|^2.0",
32+
"symfony/dom-crawler": "^5.4|^6.1"
33+
},
34+
"require-dev": {
35+
"laravel/pint": "^1.0",
36+
"phpstan/phpstan": "^1.8"
37+
},
38+
"autoload": {
39+
"psr-4": {
40+
"Raiolanetworks\\PluginSEOTest\\": "src"
41+
}
42+
},
43+
"autoload-dev": {
44+
"psr-4": {
45+
"Raiolanetworks\\PluginSEOTest\\Tests\\": "tests"
46+
}
47+
},
48+
"scripts": {
49+
"analyse": "vendor/bin/phpstan analyse -c phpstan.neon.dist",
50+
"test": "vendor/bin/phpunit",
51+
"test-coverage": "vendor/bin/phpunit --coverage",
52+
"format": "vendor/bin/pint"
53+
},
54+
"config": {
55+
"sort-packages": true
56+
},
57+
"replace": {
58+
"juampi92/test-seo": "*"
59+
},
60+
"minimum-stability": "dev",
61+
"prefer-stable": true
5162
}

src/Parser/HTMLParser.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22

3-
namespace Juampi92\TestSEO\Parser;
3+
declare(strict_types=1);
4+
5+
namespace Raiolanetworks\PluginSEOTest\Parser;
46

57
use DOMElement;
68
use DOMNode;
@@ -21,7 +23,7 @@ public function grabTextFrom(string $xpath): ?string
2123
}
2224

2325
/**
24-
* @param string|array<string> $attributes
26+
* @param string|array<string> $attributes
2527
* @return string|array<string, string|null>|null
2628
*/
2729
public function grabAttributeFrom(string $xpath, $attributes)
@@ -36,12 +38,12 @@ public function grabAttributeFrom(string $xpath, $attributes)
3638
}
3739

3840
/**
39-
* @param string|array<string>|null $attribute
41+
* @param string|array<string>|null $attribute
4042
*/
4143
public function grabMultiple(string $xpath, $attribute = null): array
4244
{
4345
$result = [];
44-
$nodes = $this->crawler->filterXPath($xpath);
46+
$nodes = $this->crawler->filterXPath($xpath);
4547

4648
foreach ($nodes as $node) {
4749
$result[] = $attribute !== null ? $this->getArgumentsFromNode($node, $attribute) : $node->textContent;
@@ -51,8 +53,8 @@ public function grabMultiple(string $xpath, $attribute = null): array
5153
}
5254

5355
/**
54-
* @param DOMElement|DOMNode|null $element
55-
* @param string|array<string> $attributes
56+
* @param DOMElement|DOMNode|null $element
57+
* @param string|array<string> $attributes
5658
* @return string|array<string, string|null>
5759
*/
5860
private function getArgumentsFromNode($element, $attributes)

src/SEOData.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<?php
22

3-
namespace Juampi92\TestSEO;
3+
declare(strict_types=1);
4+
5+
namespace Raiolanetworks\PluginSEOTest;
46

57
use Illuminate\Support\Traits\Macroable;
6-
use Juampi92\TestSEO\Parser\HTMLParser;
7-
use Juampi92\TestSEO\Support\ArrayPluck;
8-
use Juampi92\TestSEO\Support\Memo;
9-
use Juampi92\TestSEO\Tags\AlternateHrefLangCollection;
10-
use Juampi92\TestSEO\Tags\Robots;
11-
use Juampi92\TestSEO\Tags\TagCollection;
8+
use Raiolanetworks\PluginSEOTest\Parser\HTMLParser;
9+
use Raiolanetworks\PluginSEOTest\Support\ArrayPluck;
10+
use Raiolanetworks\PluginSEOTest\Support\Memo;
11+
use Raiolanetworks\PluginSEOTest\Tags\AlternateHrefLangCollection;
12+
use Raiolanetworks\PluginSEOTest\Tags\Robots;
13+
use Raiolanetworks\PluginSEOTest\Tags\TagCollection;
1214
use Spatie\Url\Url;
1315

1416
class SEOData
@@ -18,8 +20,7 @@ class SEOData
1820

1921
public function __construct(
2022
private HTMLParser $html
21-
) {
22-
}
23+
) {}
2324

2425
public function title(): ?string
2526
{

src/SnapshotFormatters/SimpleSerializer.php

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
11
<?php
22

3-
namespace Juampi92\TestSEO\SnapshotFormatters;
3+
declare(strict_types=1);
44

5-
use Juampi92\TestSEO\SEOData;
6-
use Juampi92\TestSEO\Tags\TagCollection;
5+
namespace Raiolanetworks\PluginSEOTest\SnapshotFormatters;
6+
7+
use Raiolanetworks\PluginSEOTest\SEOData;
8+
use Raiolanetworks\PluginSEOTest\Tags\TagCollection;
79

810
class SimpleSerializer implements SnapshotSerializer
911
{
1012
public function toArray(SEOData $data): array
1113
{
1214
return [
13-
'title' => $data->title(),
14-
'description' => $data->description(),
15-
'robots' => (string) $data->robots(),
16-
'canonical' => $this->formatUrl($data->canonical()),
17-
'pagination' => [
15+
'title' => $data->title(),
16+
'description' => $data->description(),
17+
'robots' => (string) $data->robots(),
18+
'canonical' => $this->formatUrl($data->canonical()),
19+
'pagination' => [
1820
'prev' => $this->formatUrl($data->prev()),
1921
'next' => $this->formatUrl($data->next()),
2022
],
2123
'relAltHreflang' => array_map(
2224
fn (array $item) => [
2325
'hreflang' => $item['hreflang'],
24-
'href' => $this->formatUrl($item['href']),
26+
'href' => $this->formatUrl($item['href']),
2527
],
2628
$data->alternateHrefLang()->jsonSerialize()
2729
),
28-
'h1' => $data->h1s(),
29-
'opengraph' => $this->formatTagCollection($data->openGraph()),
30-
'twitter' => $this->formatTagCollection($data->twitter()),
30+
'h1' => $data->h1s(),
31+
'opengraph' => $this->formatTagCollection($data->openGraph()),
32+
'twitter' => $this->formatTagCollection($data->twitter()),
3133
];
3234
}
3335

src/SnapshotFormatters/SnapshotSerializer.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<?php
22

3-
namespace Juampi92\TestSEO\SnapshotFormatters;
3+
declare(strict_types=1);
44

5-
use Juampi92\TestSEO\SEOData;
5+
namespace Raiolanetworks\PluginSEOTest\SnapshotFormatters;
6+
7+
use Raiolanetworks\PluginSEOTest\SEOData;
68

79
interface SnapshotSerializer
810
{

0 commit comments

Comments
 (0)