Skip to content

Commit

Permalink
Added og:image and alt text checks to linter for Stories (#755)
Browse files Browse the repository at this point in the history
* Added og:image and alt text checks to linter for Stories

* Minor fixes to linter checks. Added testing for new checks

* Removed unused var

* Recommitting for CI build, No code changes

* Code cleanup

Co-authored-by: Damani Brown <[email protected]>
  • Loading branch information
Dbrown910 and Damani Brown authored May 12, 2020
1 parent c210502 commit b262d7c
Show file tree
Hide file tree
Showing 8 changed files with 849 additions and 1 deletion.
4 changes: 4 additions & 0 deletions packages/linter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { SxgVaryOnAcceptAct } from "./rules/SxgVaryOnAcceptAct";
import { SxgContentNegotiationIsOk } from "./rules/SxgContentNegotiationIsOk";
import { SxgDumpSignedExchangeVerify } from "./rules/SxgDumpSignedExchangeVerify";
import { SxgAmppkgIsForwarded } from "./rules/SxgAmppkgIsForwarded";
import { MetadataIncludesOGImageSrc } from "./rules/MetadataIncludesOGImageSrc";
import { ImagesHaveAltText } from "./rules/ImagesHaveAltText";
import { RuleConstructor } from "./rule";
import { isArray } from "util";

Expand Down Expand Up @@ -100,6 +102,8 @@ function testsForMode(type: LintMode) {
StoryMetadataIsV1,
StoryIsMostlyText,
StoryMetadataThumbnailsAreOk,
MetadataIncludesOGImageSrc,
ImagesHaveAltText,
])
);
return tests.get(type) || [];
Expand Down
25 changes: 25 additions & 0 deletions packages/linter/src/rules/ImagesHaveAltText.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Context } from "../index";
import { Rule } from "../rule";

export class ImagesHaveAltText extends Rule {
run({ $ }: Context) {
let imgsWithoutAlt = "";

$("amp-img").each(function (i, elem) {
if (!elem.attribs.alt) {
imgsWithoutAlt = imgsWithoutAlt + "- " + elem.attribs.src + "\n";
}
});

return imgsWithoutAlt.length > 0
? this.warn(`Missing alt text from images: \n` + imgsWithoutAlt)
: this.pass();
}
meta() {
return {
url: "https://blog.amp.dev/2020/02/12/seo-for-amp-stories/",
title: "Images contain alt text",
info: "",
};
}
}
30 changes: 30 additions & 0 deletions packages/linter/src/rules/MetadataIncludesOGImageSrc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Context } from "../index";
import { Rule } from "../rule";

export class MetadataIncludesOGImageSrc extends Rule {
run({ $ }: Context) {
let hasOGImage = false;

$("meta").each(function (i, elem) {
if (
elem.attribs.property &&
elem.attribs.property.includes("og:image", 0) &&
elem.attribs.content
) {
hasOGImage = true;
return false;
}
});

return !hasOGImage
? this.warn(`Missing og:image property or content source`)
: this.pass();
}
meta() {
return {
url: "https://blog.amp.dev/2020/02/12/seo-for-amp-stories/",
title: "Metadata includes og:image and src",
info: "",
};
}
}
30 changes: 29 additions & 1 deletion packages/linter/tests/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { MetaCharsetIsFirst } from "../src/rules/MetaCharsetIsFirst";
import { RuntimeIsPreloaded } from "../src/rules/RuntimeIsPreloaded";
import { SchemaMetadataIsNews } from "../src/rules/SchemaMetadataIsNews";
import { StoryRuntimeIsV1 } from "../src/rules/StoryRuntimeIsV1";
import { ImagesHaveAltText } from "../src/rules/ImagesHaveAltText";
import { MetadataIncludesOGImageSrc } from "../src/rules/MetadataIncludesOGImageSrc";
import { basename } from "path";
import { BookendExists } from "../src/rules/BookendExists";

Expand Down Expand Up @@ -102,5 +104,31 @@ assertWarn(
runLocalTest(BookendExists, "local/BookendExists-3/source.html")
);

assertPass(
`${MetadataIncludesOGImageSrc.name} - <meta property="og:image"> is present`,
runLocalTest(
MetadataIncludesOGImageSrc,
"local/MetadataIncludesOGImageSrc-1/source.html"
)
);

assertWarn(
`${MetadataIncludesOGImageSrc.name} - <meta property="og:image"> is missing`,
runLocalTest(
MetadataIncludesOGImageSrc,
"local/MetadataIncludesOGImageSrc-2/source.html"
)
);

assertPass(
`${ImagesHaveAltText.name} - All <amp-img> have alt text`,
runLocalTest(ImagesHaveAltText, "local/ImagesHaveAltText-1/source.html")
);

assertWarn(
`${ImagesHaveAltText.name} - At least one <amp-img> is missing alt text`,
runLocalTest(ImagesHaveAltText, "local/ImagesHaveAltText-2/source.html")
);

console.log(`# ${basename(__filename)} - HTML-only tests`);
console.log(`1..16`);
console.log(`1..20`);
92 changes: 92 additions & 0 deletions packages/linter/tests/local/ImagesHaveAltText-1/source.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!doctype html>
<html amp lang="en">
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js" rel="preload"></script>
<style amp-boilerplate>
body {
-webkit-animation: -amp-start 8s steps(1,end) 0s 1 normal both;
-moz-animation: -amp-start 8s steps(1,end) 0s 1 normal both;
-ms-animation: -amp-start 8s steps(1,end) 0s 1 normal both;
animation: -amp-start 8s steps(1,end) 0s 1 normal both
}

@-webkit-keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}

@-moz-keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}

@-ms-keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}

@-o-keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}

@keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}
</style>
<noscript>
<style amp-boilerplate>
body {
-webkit-animation: none;
-moz-animation: none;
-ms-animation: none;
animation: none
}
</style>
</noscript>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
<title>Through the fence 2020</title>
<script async custom-element="amp-story" src="https://cdn.ampproject.org/v0/amp-story-1.0.js"></script>
</head>
<body>
<amp-story standalone poster-portrait-src="https://ss.makestories.io/get?story=-M6q2XpFIDyuU4zoj45u&version=1588971636320&width=696&height=1237" publisher-logo-src="https://app.makestories.io/images/favicon.png" publisher="MakeStories" title="Through the fence 2020">
<amp-story-page id="pggaspiqcb" class="pggaspiqcb ms-st-pg">
<amp-story-grid-layer template="fill" class="pbvnsupp">
<amp-img width="720" height="1280" layout="responsive" class="pbvnsup" id="pggaspiqcb-bg" src="https://images.unsplash.com/photo-1586021412933-1973b937d8d3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjI1MTY2fQ&q=85&w=2160" alt="Background Image"></amp-img>
</amp-story-grid-layer>
<amp-story-grid-layer template="vertical" id="sihdy">
<h1 class="ubqhi pa" id="leovpcjjbg">Through The Fence 2020</h1>
</amp-story-grid-layer>
</amp-story-page>
<amp-story-bookend srca="bookend.json" layout="nodisplay"></amp-story-bookend>
</amp-story>
</body>
</html>
92 changes: 92 additions & 0 deletions packages/linter/tests/local/ImagesHaveAltText-2/source.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!doctype html>
<html amp lang="en">
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js" rel="preload"></script>
<style amp-boilerplate>
body {
-webkit-animation: -amp-start 8s steps(1,end) 0s 1 normal both;
-moz-animation: -amp-start 8s steps(1,end) 0s 1 normal both;
-ms-animation: -amp-start 8s steps(1,end) 0s 1 normal both;
animation: -amp-start 8s steps(1,end) 0s 1 normal both
}

@-webkit-keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}

@-moz-keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}

@-ms-keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}

@-o-keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}

@keyframes -amp-start {
from {
visibility: hidden
}

to {
visibility: visible
}
}
</style>
<noscript>
<style amp-boilerplate>
body {
-webkit-animation: none;
-moz-animation: none;
-ms-animation: none;
animation: none
}
</style>
</noscript>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
<title>Through the fence 2020</title>
<script async custom-element="amp-story" src="https://cdn.ampproject.org/v0/amp-story-1.0.js"></script>
</head>
<body>
<amp-story standalone poster-portrait-src="https://ss.makestories.io/get?story=-M6q2XpFIDyuU4zoj45u&version=1588971636320&width=696&height=1237" publisher-logo-src="https://app.makestories.io/images/favicon.png" publisher="MakeStories" title="Through the fence 2020">
<amp-story-page id="pggaspiqcb" class="pggaspiqcb ms-st-pg">
<amp-story-grid-layer template="fill" class="pbvnsupp">
<amp-img width="720" height="1280" layout="responsive" class="pbvnsup" id="pggaspiqcb-bg" src="https://images.unsplash.com/photo-1586021412933-1973b937d8d3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjI1MTY2fQ&q=85&w=2160"></amp-img>
</amp-story-grid-layer>
<amp-story-grid-layer template="vertical" id="sihdy">
<h1 class="ubqhi pa" id="leovpcjjbg">Through The Fence 2020</h1>
</amp-story-grid-layer>
</amp-story-page>
<amp-story-bookend srca="bookend.json" layout="nodisplay"></amp-story-bookend>
</amp-story>
</body>
</html>
Loading

0 comments on commit b262d7c

Please sign in to comment.