Best K6 code snippet using html.NoModule
reorderhead_test.go
Source:reorderhead_test.go
1// Copyright 2018 Google LLC2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// https://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14package transformers_test15import (16 "strings"17 "testing"18 "github.com/ampproject/amppackager/transformer/internal/amphtml"19 tt "github.com/ampproject/amppackager/transformer/internal/testing"20 "github.com/ampproject/amppackager/transformer/transformers"21 "golang.org/x/net/html"22)23func TestReorderHead(t *testing.T) {24 tcs := []tt.TestCase{25 {26 Desc: "Reorders head children for AMP document",27 Input: tt.Concat(tt.Doctype, "<html â¡><head>",28 tt.Title, tt.StyleAMPBoilerplate,29 tt.ScriptAMPExperiment, tt.ScriptAMPAudio,30 tt.NoscriptAMPBoilerplate, tt.StyleAMPRuntime,31 tt.ScriptAMPRuntime, tt.LinkGoogleFont,32 tt.LinkGoogleFontPreconnect, tt.MetaCharset,33 tt.MetaViewport, tt.StyleAMPCustom, tt.LinkCanonical,34 tt.LinkFavicon, tt.ScriptAMPViewerRuntime,35 tt.ScriptAMPMustache, tt.ScriptAMPMraid,36 "</head><body></body></html>"),37 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",38 // (0) <meta charset> tag39 tt.MetaCharset,40 // (1) <style amp-runtime> (inserted by ampruntimecss.go)41 tt.StyleAMPRuntime,42 // (2) remaining <meta> tags (those other than <meta charset>)43 tt.MetaViewport,44 // (3) AMP runtime .js <script> tag45 tt.ScriptAMPRuntime,46 // (4) AMP viewer runtime .js <script> tag (inserted by AmpViewerScript)47 tt.ScriptAMPViewerRuntime,48 // (5) <script> tags that are render delaying49 tt.ScriptAMPExperiment,50 // (6) <script> tags for remaining extensions51 tt.ScriptAMPAudio,52 tt.ScriptAMPMraid,53 tt.ScriptAMPMustache,54 // (7) <link> tag for favicons55 tt.LinkFavicon,56 // (8) <link> tag for resource hints57 tt.LinkGoogleFontPreconnect,58 // (9) <link rel=stylesheet> tags before <style amp-custom>59 tt.LinkGoogleFont,60 // (10) <style amp-custom>61 tt.StyleAMPCustom,62 // (11) any other tags allowed in <head>63 tt.Title,64 tt.LinkCanonical,65 // (12) amp boilerplate (first style amp-boilerplate, then noscript)66 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,67 "</head><body></body></html>"),68 },69 {70 Desc: "Reorders head children for module/nomodule AMP document",71 Input: tt.Concat(tt.Doctype, "<html â¡><head>",72 tt.Title, tt.StyleAMPBoilerplate,73 tt.ScriptAMPExperimentNomodule, tt.ScriptAMPAudioNomodule,74 tt.ScriptAMPExperimentModule, tt.ScriptAMPAudioModule,75 tt.NoscriptAMPBoilerplate, tt.StyleAMPRuntime,76 tt.ScriptAMPRuntimeModule, tt.ScriptAMPRuntimeNomodule,77 tt.LinkGoogleFont, tt.LinkGoogleFontPreconnect, tt.MetaCharset,78 tt.MetaViewport, tt.StyleAMPCustom, tt.LinkCanonical,79 tt.LinkFavicon, tt.ScriptAMPViewerRuntime,80 tt.ScriptAMPMustacheNomodule, tt.ScriptAMPMustacheModule,81 tt.ScriptAMPMraidNomodule, tt.ScriptAMPMraidModule,82 "</head><body></body></html>"),83 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",84 // (0) <meta charset> tag85 tt.MetaCharset,86 // (1) <style amp-runtime> (inserted by ampruntimecss.go)87 tt.StyleAMPRuntime,88 // (2) remaining <meta> tags (those other than <meta charset>)89 tt.MetaViewport,90 // (3) AMP runtime module/nomodule <script> tags91 tt.ScriptAMPRuntimeModule, tt.ScriptAMPRuntimeNomodule,92 // (4) AMP viewer runtime .js <script> tag (inserted by AmpViewerScript)93 tt.ScriptAMPViewerRuntime,94 // (5) <script> tags that are render delaying95 tt.ScriptAMPExperimentNomodule, tt.ScriptAMPExperimentModule,96 // (6) <script> tags for remaining extensions97 tt.ScriptAMPAudioNomodule, tt.ScriptAMPAudioModule,98 tt.ScriptAMPMraidNomodule, tt.ScriptAMPMraidModule,99 tt.ScriptAMPMustacheNomodule, tt.ScriptAMPMustacheModule,100 // (7) <link> tag for favicons101 tt.LinkFavicon,102 // (8) <link> tag for resource hints103 tt.LinkGoogleFontPreconnect,104 // (9) <link rel=stylesheet> tags before <style amp-custom>105 tt.LinkGoogleFont,106 // (10) <style amp-custom>107 tt.StyleAMPCustom,108 // (11) any other tags allowed in <head>109 tt.Title,110 tt.LinkCanonical,111 // (12) amp boilerplate (first style amp-boilerplate, then noscript)112 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,113 "</head><body></body></html>"),114 },115 {116 Desc: "Reorders head children for AMP4ADS document",117 Input: tt.Concat(tt.Doctype, "<html â¡4ads><head>",118 tt.Title, tt.StyleAMP4AdsBoilerplate, tt.ScriptAMPAudio,119 tt.ScriptAMP4AdsRuntime, tt.LinkGoogleFont,120 tt.LinkGoogleFontPreconnect, tt.MetaCharset, tt.MetaViewport, tt.StyleAMPCustom,121 "</head><body></body></html>"),122 Expected: tt.Concat(tt.Doctype, "<html â¡4ads><head>",123 // (0) <meta charset> tag124 tt.MetaCharset,125 // (1) <style amp-runtime> (inserted by ampruntimecss.go)126 // n/a for AMP4ADS127 // (2) remaining <meta> tags (those other than <meta charset>)128 tt.MetaViewport,129 // (3) AMP runtime .js <script> tag130 tt.ScriptAMP4AdsRuntime,131 // (4) AMP viewer runtime .js <script> tag (inserted by AmpViewerScript)132 // n/a for AMP4ADS, no viewer133 // (5) <script> tags that are render delaying134 // n/a for AMP4ADS, no render delaying <script> tags allowed135 // (6) <script tags> for remaining extensions136 tt.ScriptAMPAudio,137 // (7) <link> tag for favicons138 // n/a for AMP4ADS, no favicons allowed139 // (8) <link> tag for resource hints140 tt.LinkGoogleFontPreconnect,141 // (9) <link rel=stylesheet> tags before <style amp-custom>142 tt.LinkGoogleFont,143 // (10) <style amp-custom>144 tt.StyleAMPCustom,145 // (11) any other tags allowed in <head>146 tt.Title,147 // (12) amp boilerplate (first style amp-boilerplate, then noscript)148 tt.StyleAMP4AdsBoilerplate,149 "</head><body></body></html>"),150 },151 {152 Desc: "Preserves style sheet ordering",153 Input: tt.Concat(tt.Doctype, "<html â¡><head>",154 tt.MetaCharset, tt.MetaViewport, tt.ScriptAMPRuntime,155 tt.LinkFavicon, tt.LinkGoogleFont, tt.StyleAMPCustom,156 "<link href=another-font rel=stylesheet>",157 tt.LinkCanonical, tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,158 "</head><body></body></html>"),159 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",160 tt.MetaCharset, tt.MetaViewport, tt.ScriptAMPRuntime,161 tt.LinkFavicon, tt.LinkGoogleFont, tt.StyleAMPCustom,162 "<link href=another-font rel=stylesheet>",163 tt.LinkCanonical, tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,164 "</head><body></body></html>"),165 },166 {167 Desc: "AMP Runtime script is reordered as first script",168 Input: tt.Concat(tt.Doctype, "<html â¡><head>",169 tt.MetaCharset, tt.MetaViewport,170 tt.ScriptAMPAudio, tt.ScriptAMPRuntime,171 tt.LinkFavicon, tt.LinkCanonical,172 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,173 "</head><body></body></html>"),174 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",175 tt.MetaCharset, tt.MetaViewport,176 tt.ScriptAMPRuntime, tt.ScriptAMPAudio,177 tt.LinkFavicon, tt.LinkCanonical,178 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,179 "</head><body></body></html>"),180 },181 {182 Desc: "Render delaying scripts before non-render delaying scripts",183 Input: tt.Concat(tt.Doctype, "<html â¡><head>",184 tt.MetaCharset, tt.MetaViewport,185 tt.ScriptAMPRuntime, tt.ScriptAMPAudio, tt.ScriptAMPExperiment,186 tt.LinkFavicon, tt.LinkCanonical,187 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,188 "</head><body></body></html>"),189 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",190 tt.MetaCharset, tt.MetaViewport,191 tt.ScriptAMPRuntime, tt.ScriptAMPExperiment, tt.ScriptAMPAudio,192 tt.LinkFavicon, tt.LinkCanonical,193 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,194 "</head><body></body></html>"),195 },196 {197 Desc: "Removes duplicate custom element script",198 Input: tt.Concat(tt.Doctype, "<html â¡><head>",199 tt.MetaCharset, tt.MetaViewport,200 tt.ScriptAMPRuntime, tt.ScriptAMPAudio, tt.ScriptAMPAudio,201 tt.LinkFavicon, tt.LinkCanonical,202 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,203 "</head><body></body></html>"),204 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",205 tt.MetaCharset, tt.MetaViewport,206 tt.ScriptAMPRuntime, tt.ScriptAMPAudio,207 tt.LinkFavicon, tt.LinkCanonical,208 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,209 "</head><body></body></html>"),210 },211 {212 Desc: "Sorts custom element scripts",213 Input: tt.Concat(tt.Doctype, "<html â¡><head>",214 tt.MetaCharset, tt.MetaViewport,215 tt.ScriptAMPRuntime, tt.ScriptAMPExperiment, tt.ScriptAMPDynamicCSSClasses,216 tt.LinkFavicon, tt.LinkCanonical,217 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,218 "</head><body></body></html>"),219 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",220 tt.MetaCharset, tt.MetaViewport,221 tt.ScriptAMPRuntime, tt.ScriptAMPDynamicCSSClasses, tt.ScriptAMPExperiment,222 tt.LinkFavicon, tt.LinkCanonical,223 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,224 "</head><body></body></html>"),225 },226 {227 Desc: "Removes duplicate custom template script",228 Input: tt.Concat(tt.Doctype, "<html â¡><head>",229 tt.MetaCharset, tt.MetaViewport,230 tt.ScriptAMPRuntime, tt.ScriptAMPMustache, tt.ScriptAMPMustache,231 tt.LinkFavicon, tt.LinkCanonical,232 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,233 "</head><body></body></html>"),234 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",235 tt.MetaCharset, tt.MetaViewport,236 tt.ScriptAMPRuntime, tt.ScriptAMPMustache,237 tt.LinkFavicon, tt.LinkCanonical,238 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,239 "</head><body></body></html>"),240 },241 {242 Desc: "Preserves multiple favicons",243 Input: tt.Concat(tt.Doctype, "<html â¡><head>",244 tt.MetaCharset, tt.MetaViewport,245 tt.ScriptAMPRuntime, tt.ScriptAMPAudio,246 tt.LinkFavicon, tt.LinkFavicon, tt.LinkCanonical,247 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,248 "</head><body></body></html>"),249 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",250 tt.MetaCharset, tt.MetaViewport,251 tt.ScriptAMPRuntime, tt.ScriptAMPAudio,252 tt.LinkFavicon, tt.LinkFavicon, tt.LinkCanonical,253 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,254 "</head><body></body></html>"),255 },256 {257 Desc: "Case insensitive rel value",258 Input: tt.Concat(tt.Doctype, "<html â¡><head>",259 tt.MetaCharset, tt.MetaViewport,260 tt.ScriptAMPRuntime, tt.ScriptAMPAudio, tt.LinkCanonical,261 tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,262 `<link href=https://example.com/favicon.ico rel="Shortcut Icon">`,263 "</head><body></body></html>"),264 Expected: tt.Concat(tt.Doctype, "<html â¡><head>",265 tt.MetaCharset, tt.MetaViewport,266 tt.ScriptAMPRuntime, tt.ScriptAMPAudio,267 `<link href=https://example.com/favicon.ico rel="Shortcut Icon">`,268 tt.LinkCanonical, tt.StyleAMPBoilerplate, tt.NoscriptAMPBoilerplate,269 "</head><body></body></html>"),270 },271 }272 runReorderHeadTestcases(t, tcs)273}274func runReorderHeadTestcases(t *testing.T, tcs []tt.TestCase) {275 for _, tc := range tcs {276 inputDoc, err := html.Parse(strings.NewReader(tc.Input))277 if err != nil {278 t.Errorf("%s: html.Parse for %s failed %q", tc.Desc, tc.Input, err)279 continue280 }281 inputDOM, err := amphtml.NewDOM(inputDoc)282 if err != nil {283 t.Errorf("%s\namphtml.NewDOM for %s failed %q", tc.Desc, tc.Input, err)284 continue285 }286 transformers.ReorderHead(&transformers.Context{DOM: inputDOM})287 var input strings.Builder288 if err := html.Render(&input, inputDoc); err != nil {289 t.Errorf("%s: html.Render for %s failed %q", tc.Desc, tc.Input, err)290 continue291 }292 expectedDoc, err := html.Parse(strings.NewReader(tc.Expected))293 if err != nil {294 t.Errorf("%s: html.Parse for %s failed %q", tc.Desc, tc.Expected, err)295 continue296 }297 var expected strings.Builder298 if err := html.Render(&expected, expectedDoc); err != nil {299 t.Errorf("%s: html.Render for %s failed %q", tc.Desc, tc.Expected, err)300 continue301 }302 if input.String() != expected.String() {303 t.Errorf("%s: ReorderHead=\n%q\nwant=\n%q", tc.Desc, &input, &expected)304 }305 }306}...
testing.go
Source:testing.go
1// Copyright 2018 Google LLC2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// https://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14/*15Package testing provides test constants and utilities for the transformer and printer.16*/17package testing18import "strings"19// TestCase stores a description of the test case, the input HTML, and20// expected output HTML.21type TestCase struct {22 Desc string23 TransformerVersion int6424 Input string25 Expected string26}27// AMPHTML constants.28const (29 // Doctype is the doctype expected for AMP documents.30 Doctype = "<!doctype html>"31 // LinkCanonical is a link to the canonical document.32 LinkCanonical = "<link href=self.html rel=canonical>"33 // LinkFavicon is an example link tag.34 LinkFavicon = "<link href=https://example.com/favicon.ico rel=icon>"35 // LinkGoogleFont is a Google Font stylesheet.36 LinkGoogleFont = "<link href=https://fonts.googleapis.com/css?family=Roboto rel=stylesheet>"37 // LinkGoogleFontEarlyAccess is a Google Font Early Access stylesheet.38 LinkGoogleFontEarlyAccess = "<link href=https://fonts.googleapis.com/earlyaccess/hannari.css>"39 // LinkGoogleFontIcon is a Google Font Icon stylesheet.40 LinkGoogleFontIcon = "<link href=https://fonts.googleapis.com/icon?bolt rel=stylesheet>"41 // LinkGoogleFontDisplayBlock is a Google Font stylesheet with href including display=block component.42 LinkGoogleFontDisplayBlock = "<link href=https://fonts.googleapis.com/css?family=Roboto&display=block rel=stylesheet>"43 // LinkGoogleFontDisplayOptional is a Google Font stylesheet with href including display=optional component.44 LinkGoogleFontDisplayOptional = "<link href=https://fonts.googleapis.com/css?family=Roboto&display=optional rel=stylesheet>"45 // LinkGoogleFontPreconnect is a preconnect for Google Fonts.46 LinkGoogleFontPreconnect = "<link crossorigin=\"\" href=https://fonts.gstatic.com/ rel=\"dns-prefetch preconnect\">"47 // MetaCharset is a required tag for an AMP document.48 MetaCharset = "<meta charset=utf-8>"49 // MetaViewport is a required tag for an AMP document.50 MetaViewport = "<meta content=width=device-width,minimum-scale=1,initial-scale=1 name=viewport>"51 // NoscriptAMPBoilerplate is the standard style for <noscript> tag.52 NoscriptAMPBoilerplate = "<noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>"53 // ScriptAMPAccess is the script for amp-access.54 ScriptAMPAccess = "<script async custom-element=amp-access src=https://cdn.ampproject.org/v0/amp-accesss-0.1.js></script>"55 // ScriptAMPAd is the script for amp-ad.56 ScriptAMPAd = "<script async custom-element=amp-ad src=https://cdn.ampproject.org/v0/amp-ad-0.1.js></script>"57 // ScriptAMPAnalytics is the script for amp-analytics.58 ScriptAMPAnalytics = "<script async custom-element=amp-analytics src=https://cdn.ampproject.org/v0/amp-analytics-0.1.js></script>"59 // ScriptAMPAudio is the script for amp-audio.60 ScriptAMPAudio = "<script async custom-element=amp-audio src=https://cdn.ampproject.org/v0/amp-audio-0.1.js></script>"61 // ScriptAMPAudioModule is the module script for amp-audio.62 ScriptAMPAudioModule = "<script async custom-element=amp-audio src=https://cdn.ampproject.org/v0/amp-audio-0.1.mjs type=module></script>"63 // ScriptAMPAudioNomodule is the nomodule script for amp-audio.64 ScriptAMPAudioNomodule = "<script async custom-element=amp-audio nomodule src=https://cdn.ampproject.org/v0/amp-audio-0.1.js></script>"65 // ScriptAMPDynamicCSSClasses is the script for amp-dynamic-css-class.66 ScriptAMPDynamicCSSClasses = "<script async custom-element=amp-dynamic-css-classes src=https://cdn.ampproject.org/v0/amp-dynamic-css-classes-0.1.js></script>"67 // ScriptAMPExperiment is the script for amp-experiment.68 ScriptAMPExperiment = "<script async custom-element=amp-experiment src=https://cdn.ampproject.org/v0/amp-experiment-0.1.js></script>"69 // ScriptAMPExperimentModule is the module script for amp-experiment.70 ScriptAMPExperimentModule = "<script async custom-element=amp-experiment src=https://cdn.ampproject.org/v0/amp-experiment-0.1.mjs type=module></script>"71 // ScriptAMPExperimentNomodule is the nomodule script for amp-experiment.72 ScriptAMPExperimentNomodule = "<script async custom-element=amp-experiment nomodule src=https://cdn.ampproject.org/v0/amp-experiment-0.1.js></script>"73 // ScriptAMPForm is the script for amp-form.74 ScriptAMPForm = "<script async custom-element=amp-form src=https://cdn.ampproject.org/v0/amp-form-0.1.js></script>"75 // ScriptAMPMraid is the script for amp-mraid.76 ScriptAMPMraid = "<script async host-service=amp-mraid src=https://cdn.ampproject.org/v0/amp-mraid-0.1.js></script>"77 // ScriptAMPMraidModule is the module script for amp-mraid.78 ScriptAMPMraidModule = "<script async host-service=amp-mraid src=https://cdn.ampproject.org/v0/amp-mraid-0.1.mjs type=module></script>"79 // ScriptAMPMraidNomodule is the nomodule script for amp-mraid.80 ScriptAMPMraidNomodule = "<script async host-service=amp-mraid nomodule src=https://cdn.ampproject.org/v0/amp-mraid-0.1.js></script>"81 // ScriptAMPMustache is the script for amp-mustache.82 ScriptAMPMustache = "<script async custom-template=amp-mustache src=https://cdn.ampproject.org/v0/amp-mustache-0.1.js></script>"83 // ScriptAMPMustacheModule is the module script for amp-mustache.84 ScriptAMPMustacheModule = "<script async custom-template=amp-mustache src=https://cdn.ampproject.org/v0/amp-mustache-0.1.mjs type=module></script>"85 // ScriptAMPMustacheNomodule is the nomodule script for amp-mustache.86 ScriptAMPMustacheNomodule = "<script async custom-template=amp-mustache nomodule src=https://cdn.ampproject.org/v0/amp-mustache-0.1.js></script>"87 // ScriptAMPRuntime is the AMP script tag.88 ScriptAMPRuntime = "<script async src=https://cdn.ampproject.org/v0.js></script>"89 // ScriptAMPRuntimeModule is the AMP module script tag.90 ScriptAMPRuntimeModule = "<script async src=https://cdn.ampproject.org/v0.mjs type=module></script>"91 // ScriptAMPRuntimeNomodule is the AMP nomodule script tag.92 ScriptAMPRuntimeNomodule = "<script async nomodule src=https://cdn.ampproject.org/v0.js></script>"93 // ScriptAMPViewerRuntime is the AMP viewer runtime script tag.94 ScriptAMPViewerRuntime = "<script async src=https://cdn.ampproject.org/v0/amp-viewer-integration-0.1.js></script>"95 // ScriptAMP4AdsRuntime is the AMP4Ads script tag.96 ScriptAMP4AdsRuntime = "<script async src=https://cdn.ampproject.org/amp4ads-v0.js></script>"97 // ScriptAMPStory is the script for amp-story.98 ScriptAMPStory = "<script async custom-element=amp-story src=https://cdn.ampproject.org/v0/amp-story-0.1.js></script>"99 // StyleAMP4AdsBoilerplate is the script for amp4ads boilerplate.100 StyleAMP4AdsBoilerplate = "<style amp4ads-boilerplate>body{visibility;hidden}</style>"101 // StyleAMP4EmailBoilerplate is the script for amp4email boilerplate.102 StyleAMP4EmailBoilerplate = "<style amp4email-boilerplate>body{visibility;hidden}</style>"103 // StyleAMPBoilerplate is the standard style.104 StyleAMPBoilerplate = "<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>"105 // StyleAMPCustom is a customized stylesheet for an AMP document.106 StyleAMPCustom = "<style amp-custom>#lemur { color: #adaaad }</style>"107 // StyleAMPRuntime is an injected tag from server-side rendering.108 StyleAMPRuntime = "<style amp-runtime></style>"109 // Title is a title tag for an AMP document.110 Title = "<title>Hello AMP</title>"111)112// Concat concatenates the given strings together.113func Concat(strs ...string) string {114 return strings.Join(strs, "")115}...
stripjs_test.go
Source:stripjs_test.go
1// Copyright 2018 Google LLC2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// https://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14package transformers_test15import (16 "strings"17 "testing"18 "github.com/ampproject/amppackager/transformer/internal/amphtml"19 tt "github.com/ampproject/amppackager/transformer/internal/testing"20 "github.com/ampproject/amppackager/transformer/transformers"21 "golang.org/x/net/html"22)23func TestStripJS(t *testing.T) {24 tcs := []tt.TestCase{25 {26 Desc: "strips script wrong src",27 Input: "<script src=main.js/>",28 Expected: "<head></head><body></body>",29 },30 {31 Desc: "keeps script correct src",32 Input: "<script async src=\"https://cdn.ampproject.org/v0.js\"></script>",33 Expected: "<head><script async src=https://cdn.ampproject.org/v0.js></script></head>",34 },35 {36 Desc: "keeps module runtime script correct src",37 Input: "<script async crossorigin=anonymous src=\"https://cdn.ampproject.org/v0.mjs\" type=module></script>",38 Expected: "<head><script async crossorigin=anonymous src=https://cdn.ampproject.org/v0.mjs type=module></script></head>",39 },40 {41 Desc: "keeps nomodule runtime script correct src",42 Input: "<script async nomodule src=\"https://cdn.ampproject.org/v0.js\"></script>",43 Expected: "<head><script async nomodule src=https://cdn.ampproject.org/v0.js></script></head>",44 },45 {46 Desc: "keeps module extension script correct src",47 Input: "<script async crossorigin=anonymous custom-element=amp-anim src=\"https://cdn.ampproject.org/v0/amp-anim-0.1.mjs\" type=module></script>",48 Expected: "<head><script async crossorigin=anonymous custom-element=amp-anim src=https://cdn.ampproject.org/v0/amp-anim-0.1.mjs type=module></script></head>",49 },50 {51 Desc: "keeps nomodule extension script correct src",52 Input: "<script async custom-element=amp-anim nomodule src=\"https://cdn.ampproject.org/v0/amp-anim-0.1.js\"></script>",53 Expected: "<head><script async custom-element=amp-anim nomodule src=https://cdn.ampproject.org/v0/amp-anim-0.1.js></script></head>",54 },55 {56 Desc: "keeps script correct src case-insensitive",57 Input: "<script async custom-element='amp-analytics' src='https://cDn.AMPproject.org/v0/amp-analytics-0.1.js'></script>",58 Expected: "<head><script async custom-element=amp-analytics src=https://cDn.AMPproject.org/v0/amp-analytics-0.1.js></script></head>",59 },60 {61 Desc: "keeps script correct src with type",62 Input: "<script async src=\"https://cdn.ampproject.org/v0.js\" type=\"text/javascript\"></script>",63 Expected: "<head><script async src=https://cdn.ampproject.org/v0.js type=text/javascript></script></head>",64 },65 {66 Desc: "strips script no src, no type",67 Input: "<script>foo</script>",68 Expected: "<head></head><body></body>",69 },70 {71 Desc: "strips script wrong type",72 Input: "<script type=application/javascript>foo</script>",73 Expected: "<head></head><body></body>",74 },75 {76 Desc: "keeps script correct type",77 Input: "<script type=application/json>foo</script>",78 Expected: "<head><script type=application/json>foo</script></head><body></body>",79 },80 {81 Desc: "keep type=text/plain",82 Input: "<body><script type=text/plain></script></template></body>",83 Expected: "<body><script type=text/plain></script></template></body>",84 },85 {86 Desc: "strip tag attr ona",87 Input: "<body><select ona=\"myFunction()\"></body>",88 Expected: "<body><select></select></body>",89 },90 {91 Desc: "strips tag event attr",92 Input: "<body><select onchange=\"myFunction()\"></body>",93 Expected: "<body><select></select></body>",94 },95 {96 Desc: "strip tag attr onfoo",97 Input: "<body><select onfoo=\"myFunction()\"></body>",98 Expected: "<body><select></select></body>",99 },100 {101 Desc: "keep tag attr 'on'",102 Input: "<body><select on=\"myFunction()\"></body>",103 Expected: "<body><select on=myFunction()></select></body>",104 },105 {106 Desc: "keep tag attr on-foo",107 Input: "<body><select on-foo=\"myFunction()\"></body>",108 Expected: "<body><select on-foo=myFunction()></select></body>",109 },110 {111 Desc: "keep tag attr notonchange",112 Input: "<body><select notonchange=\"myFunction()\"></body>",113 Expected: "<body><select notonchange=myFunction()></select></body>",114 },115 }116 for _, tc := range tcs {117 inputDoc, err := html.Parse(strings.NewReader(tc.Input))118 if err != nil {119 t.Errorf("%s: html.Parse failed %q", tc.Input, err)120 continue121 }122 inputDOM, err := amphtml.NewDOM(inputDoc)123 if err != nil {124 t.Errorf("%s\namphtml.NewDOM for %s failed %q", tc.Desc, tc.Input, err)125 continue126 }127 transformers.StripJS(&transformers.Context{DOM: inputDOM})128 var input strings.Builder129 if err := html.Render(&input, inputDoc); err != nil {130 t.Errorf("%s: html.Render failed %q", tc.Input, err)131 continue132 }133 expectedDoc, err := html.Parse(strings.NewReader(tc.Expected))134 if err != nil {135 t.Errorf("%s: html.Parse failed %q", tc.Expected, err)136 continue137 }138 var expected strings.Builder139 err = html.Render(&expected, expectedDoc)140 if err != nil {141 t.Errorf("%s: html.Render failed %q", tc.Expected, err)142 continue143 }144 if input.String() != expected.String() {145 t.Errorf("%s: Transform=\n%q\nwant=\n%q", tc.Desc, &input, &expected)146 }147 }148}...
NoModule
Using AI Code Generation
1import (2func main() {3 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {4 fmt.Fprintf(w, "Hello, %q", html.NoEscape(r.URL.Path))5 })6 http.ListenAndServe(":8080", nil)7}8import (9func main() {10 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {11 fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))12 })13 http.ListenAndServe(":8080", nil)14}15import (16func main() {17 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {18 fmt.Fprintf(w, "Hello, %q", html.UnescapeString(r.URL.Path))19 })20 http.ListenAndServe(":8080", nil)21}22import (23func main() {24 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {25 fmt.Fprintf(w, "Hello, %q", html.QueryEscape(r.URL.Path))26 })27 http.ListenAndServe(":8080", nil)28}29import (30func main() {31 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {32 fmt.Fprintf(w, "Hello, %q", html.QueryUnescape(r.URL.Path))33 })34 http.ListenAndServe(":8080", nil)35}36import (37func main() {38 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {39 fmt.Fprintf(w, "Hello, %q", html.Escape(r.URL.Path))40 })41 http.ListenAndServe(":8080", nil)42}
NoModule
Using AI Code Generation
1import (2func main() {3 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {4 fmt.Fprintf(w, "Hello, %q", html.NoEscape(r.URL.Path))5 })6 log.Fatal(http.ListenAndServe(":8080", nil))7}
NoModule
Using AI Code Generation
1import (2func main() {3 if err != nil {4 fmt.Println(err)5 }6 defer resp.Body.Close()7 doc, err := html.Parse(resp.Body)8 if err != nil {9 fmt.Println(err)10 }11 fmt.Println(html.NoModule(doc))12}
NoModule
Using AI Code Generation
1import (2func main() {3 fmt.Println(html.NoModule)4}5import (6func main() {7 fmt.Println(html.NoModule)8}9import (10func main() {11 fmt.Println(html.NoModule)12}13import (14func main() {15 fmt.Println(html.NoModule)16}17import (18func main() {19 fmt.Println(html.NoModule)20}21import (22func main() {23 fmt.Println(html.NoModule)24}25import (26func main() {27 fmt.Println(html.NoModule)28}29import (30func main() {31 fmt.Println(html.NoModule)32}33import (34func main() {35 fmt.Println(html.NoModule)36}37import (38func main() {39 fmt.Println(html.NoModule)40}
NoModule
Using AI Code Generation
1import (2func main() {3 fmt.Println("Hello")4 if err != nil {5 log.Fatal(err)6 }7 html := htmlquery.Create(resp.Body)8 html.NoModule()9 fmt.Println(html)10}
NoModule
Using AI Code Generation
1import (2func main() {3 m := minify.New()4 m.AddFunc("text/html", html.Minify)5 m.AddFunc("text/css", css.Minify)6 m.AddFunc("text/javascript", js.Minify)7 m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)8 m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), xml.Minify)9 if err := m.Minify("text/html", os.Stdout, os.Stdin); err != nil {10 log.Fatal(err)11 }12}13import (14func main() {15 m := minify.New()16 m.AddFunc("text/html", html.Minify)17 m.AddFunc("text/css", css.Minify)18 m.AddFunc("text/javascript", js.Minify)19 m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)20 m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), xml.Minify)21 if err := m.Minify("text/html", os.Stdout, os.Stdin); err != nil {22 log.Fatal(err)23 }24}25import (26func main() {27 m := minify.New()28 m.AddFunc("text/html", html.Minify)29 m.AddFunc("text/css", css.Minify)30 m.AddFunc("text/javascript", js.Minify)31 m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)32 m.AddFuncRegexp(regexp.MustCompile("[/
NoModule
Using AI Code Generation
1import (2func main() {3 fmt.Println(html.NoModule("Go is a <gopher>"))4}5import (6func main() {7 fmt.Println(html.UnescapeString("Go is a <gopher>"))8}9import (10func main() {11 fmt.Println(html.EscapeString("Go is a <gopher>"))12}13import (14func main() {15 fmt.Println(html.Escape(nil, []byte("Go is a <gopher>")))16}17import (18func main() {19 fmt.Println(html.Unescape(nil, []byte("Go is a <gopher>")))20}21import (22func main() {23 fmt.Println(html.QueryEscape("Go is a <gopher>"))24}25import (26func main() {27 fmt.Println(html.QueryUnescape("Go+is+a+%3Cgopher%3E"))28}29import (30func main() {31 for {32 tt := tokenizer.Next()33 switch tt {
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!