Skip to content

Commit 3539ab9

Browse files
committed
Removes Lighthouse reports due to Lighthouse v12 removing PWA audits
1 parent 6948c78 commit 3539ab9

11 files changed

Lines changed: 87 additions & 154 deletions

File tree

apps/pwabuilder/Frontend/src/script/pages/app-report.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,11 @@ export class AppReport extends LitElement {
285285
}
286286

287287
analysisCompleted(): void {
288-
this.runningTests = false;
289-
if(this.analysis && !this.analysis.webManifest) {
290-
this.applyManifestContext(this.analysis.url, undefined, undefined);
291-
}
288+
this.runningTests = false;
289+
if(this.analysis) {
290+
this.applyManifestContext(this.analysis.url, this.analysis.webManifest?.url, this.analysis?.webManifest?.manifestRaw);
292291
}
292+
}
293293

294294
analysisFailed(): void {
295295
this.runningTests = false;

apps/pwabuilder/Models/Analysis.cs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -114,40 +114,6 @@ public bool MeetsRequirementsForStorePackaging()
114114
return allRequiredFieldsValid;
115115
}
116116

117-
/// <summary>
118-
/// Updates this analysis's capabilities based on the Lighthouse report.
119-
/// </summary>
120-
public void ProcessLighthouseReport(LighthouseReport? lighthouseReport)
121-
{
122-
var offlineCapability = this.Capabilities.First(c => c.Id == PwaCapabilityId.OfflineSupport);
123-
var httpsCapability = this.Capabilities.First(c => c.Id == PwaCapabilityId.HasHttps);
124-
var noMixedContentCapability = this.Capabilities.First(c => c.Id == PwaCapabilityId.NoMixedContent);
125-
var hasManifestCapability = this.Capabilities.First(c => c.Id == PwaCapabilityId.HasManifest);
126-
127-
// No lighthouse report? Mark these as skipped, and mark the "has manifest" capability as failed if we're still waiting for it.
128-
if (lighthouseReport == null)
129-
{
130-
offlineCapability.Status = PwaCapabilityCheckStatus.Skipped;
131-
httpsCapability.Status = PwaCapabilityCheckStatus.Skipped;
132-
noMixedContentCapability.Status = PwaCapabilityCheckStatus.Skipped;
133-
if (hasManifestCapability.Status == PwaCapabilityCheckStatus.InProgress)
134-
{
135-
hasManifestCapability.Status = PwaCapabilityCheckStatus.Failed;
136-
}
137-
return;
138-
}
139-
140-
offlineCapability.Status = lighthouseReport.GetOfflineCapability();
141-
httpsCapability.Status = lighthouseReport.GetHttpsCapability();
142-
noMixedContentCapability.Status = lighthouseReport.GetNoMixedContentCapability();
143-
144-
// If the "has manifest" capability is still processing, update it based on the Lighthouse report.
145-
if (hasManifestCapability.Status == PwaCapabilityCheckStatus.InProgress)
146-
{
147-
hasManifestCapability.Status = lighthouseReport.GetHasManifestCapability();
148-
}
149-
}
150-
151117
/// <summary>
152118
/// Update this analysis's capabilities based on the provided list.
153119
/// </summary>

apps/pwabuilder/Models/LighthouseReport.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ public PwaCapabilityCheckStatus GetOfflineCapability()
7575
/// <returns></returns>
7676
public PwaCapabilityCheckStatus GetHttpsCapability()
7777
{
78-
if (this.HttpsAudit == null)
78+
if (this.IsOnHttpsAudit == null)
7979
{
8080
return PwaCapabilityCheckStatus.Skipped;
8181
}
8282

83-
return this.HttpsAudit.Score == 1 ? PwaCapabilityCheckStatus.Passed : PwaCapabilityCheckStatus.Failed;
83+
return this.IsOnHttpsAudit.Score == 1 ? PwaCapabilityCheckStatus.Passed : PwaCapabilityCheckStatus.Failed;
8484
}
8585

8686
/// <summary>

apps/pwabuilder/Models/PwaCapability.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -742,21 +742,6 @@ public static List<PwaCapability> CreateHttpsCapabilities()
742742
ImageUrl = null,
743743
Category = PwaCapabilityCategory.Https,
744744
Status = PwaCapabilityCheckStatus.InProgress
745-
},
746-
new PwaCapability
747-
{
748-
Id = PwaCapabilityId.NoMixedContent,
749-
Description = "Your PWA should not served both HTTP and HTTPS content. All resources should be served over HTTPS.",
750-
TodoAction = "Fix mixed content issues by ensuring all resources are loaded over HTTPS.",
751-
Level = PwaCapabilityLevel.Recommended,
752-
FeatureName = null,
753-
FeatureIcon = null,
754-
Field = null,
755-
IsFieldExistenceCheck = false,
756-
LearnMoreUrl = new Uri("https://web.dev/articles/what-is-mixed-content"),
757-
ImageUrl = null,
758-
Category = PwaCapabilityCategory.Https,
759-
Status = PwaCapabilityCheckStatus.InProgress
760745
}
761746
];
762747
}

apps/pwabuilder/Models/PwaCapabilityId.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ public enum PwaCapabilityId
5454

5555
// Https capabilities
5656
HasHttps,
57-
NoMixedContent,
5857

5958
// General capabilities
6059
ServesHtml

apps/pwabuilder/Services/AnalysisJobProcessor.cs

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,12 @@ private async Task TryProcessJobAsync(AnalysisJob job, CancellationToken cancelT
124124

125125
// Kick off the independent jobs simultaneously so that our analysis completes faster.
126126
var generalCapDetectionTask = generalWebAppCapabilityDetector.TryDetectAsync(job.Url, analysisLogger, cancelTokenSrc.Token);
127-
var lighthouseAnalysisTask = TryRunLighthouseAudit(job, analysisLogger, cancelTokenSrc.Token);
128127
var serviceWorkerDetectionTask = serviceWorkerDetector.TryDetectAsync(job.Url, analysisLogger, cancelTokenSrc.Token);
129128
var serviceWorkerAnalysisTask = serviceWorkerDetectionTask.ContinueWith(t => serviceWorkerAnalyzer.TryAnalyzeServiceWorkerAsync(t.Result, job.Url, analysisLogger, cancelTokenSrc.Token), TaskContinuationOptions.OnlyOnRanToCompletion).Unwrap(); // This will update analysis.Capabilities.
130129
var manifestDetectionTask = manifestDetector.TryDetectAsync(job.Url, analysisLogger, cancelTokenSrc.Token);
131-
var manifestAnalysisTask = manifestDetectionTask.ContinueWith(t => manifestAnalyzer.TryAnalyzeManifestAsync(t.Result, PwaCapabilityCheckStatus.InProgress, logger, cancelTokenSrc.Token), TaskContinuationOptions.OnlyOnRanToCompletion).Unwrap();
130+
var manifestAnalysisTask = manifestDetectionTask.ContinueWith(t => manifestAnalyzer.TryAnalyzeManifestAsync(t.Result, logger, cancelTokenSrc.Token), TaskContinuationOptions.OnlyOnRanToCompletion).Unwrap();
132131

133-
// Step 1: run the general capabilities, such as whether the URL serves HTML.
134-
// We also use this to check if the URL serves HTML, and if not, to fail fast.
132+
// Step 1: run the general capabilities, such as whether the URL serves HTML. If not, we fail fast.
135133
var generalCapabilities = await generalCapDetectionTask;
136134
analysis.ProcessCapabilities(generalCapabilities);
137135
var servesHtmlStatus = FailIfNotServedHtml(analysis, cancelTokenSrc);
@@ -159,23 +157,11 @@ private async Task TryProcessJobAsync(AnalysisJob job, CancellationToken cancelT
159157
analysis.ProcessCapabilities(swCapabilities);
160158
await db.SaveAsync(analysis);
161159

162-
// Step 6, run Lighthouse analysis. This is used for offline detection, HTTPS detection, and mixed content detection.
163-
var lighthouseReport = await lighthouseAnalysisTask;
164-
analysis.LighthouseReport = lighthouseReport;
165-
analysis.ProcessLighthouseReport(lighthouseReport);
160+
// Step 6, check for HTTPS.
161+
var httpsCapabilities = TryCheckHttpsCapabilities(job.Url, analysis.WebManifest, analysis.ServiceWorker);
162+
analysis.ProcessCapabilities(httpsCapabilities);
166163
await db.SaveAsync(analysis);
167164

168-
// Step 7, if we didn't find a manifest but Lighthouse found one,
169-
// create a new ManifestDetection and rerun the manifest analyzer.
170-
// This is needed for some edge cases where the manifest isn't picked up by our manifest detection service, but is picked up by Lighthouse. Example edge case: https://www.instagram.com/?utm_source=pwa_homescreen&__pwa=1
171-
if (analysis.WebManifest == null)
172-
{
173-
analysis.WebManifest = manifestDetector.TryDetectFromLighthouse(lighthouseReport, analysisLogger);
174-
var updatedManifestCapabilities = await manifestAnalyzer.TryAnalyzeManifestAsync(analysis.WebManifest, PwaCapabilityCheckStatus.Failed, analysisLogger, cancelTokenSrc.Token);
175-
analysis.ProcessCapabilities(updatedManifestCapabilities);
176-
await db.SaveAsync(analysis);
177-
}
178-
179165
// All done! Mark the analysis as completed.
180166
analysis.Status = AnalysisStatus.Completed;
181167
analysis.Duration = DateTimeOffset.UtcNow.Subtract(analysis.CreatedAt);
@@ -211,16 +197,51 @@ private static PwaCapabilityCheckStatus FailIfNotServedHtml(Analysis analysis, C
211197
return servedHtmlCapability.Status;
212198
}
213199

214-
private async Task<LighthouseReport?> TryRunLighthouseAudit(AnalysisJob job, AnalysisLogger logger, CancellationToken cancelToken)
200+
// private async Task<LighthouseReport?> TryRunLighthouseAudit(AnalysisJob job, AnalysisLogger logger, CancellationToken cancelToken)
201+
// {
202+
// try
203+
// {
204+
// return await lighthouse.RunAuditAsync(job.Url, BrowserFormFactor.Desktop, logger, cancelToken);
205+
// }
206+
// catch (Exception error)
207+
// {
208+
// logger.LogError(error, "Error running Lighthouse audit for {url}", job.Url);
209+
// return null;
210+
// }
211+
// }
212+
213+
private List<PwaCapability> TryCheckHttpsCapabilities(Uri url, ManifestDetection? manifestDetection, ServiceWorkerDetection? swDetection)
215214
{
215+
var httpsCapabilities = PwaCapability.CreateHttpsCapabilities(); // There's only one HTTPS capability right now: has HTTPS
216216
try
217217
{
218-
return await lighthouse.RunAuditAsync(job.Url, BrowserFormFactor.Desktop, logger, cancelToken);
218+
var hasHttps = httpsCapabilities.First(c => c.Id == PwaCapabilityId.HasHttps);
219+
if (url.Scheme != Uri.UriSchemeHttps)
220+
{
221+
// Mark as failed.
222+
hasHttps.Status = PwaCapabilityCheckStatus.Failed;
223+
}
224+
225+
// If we have a manifest, check if it has any HTTP URLs.
226+
if (manifestDetection?.Url != null && manifestDetection.Url.Scheme != Uri.UriSchemeHttps)
227+
{
228+
hasHttps.Status = PwaCapabilityCheckStatus.Failed;
229+
}
230+
231+
// If we have a service worker, check if it was served over HTTPS.
232+
if (swDetection?.Url != null && swDetection.Url.Scheme != Uri.UriSchemeHttps)
233+
{
234+
hasHttps.Status = PwaCapabilityCheckStatus.Failed;
235+
}
236+
237+
hasHttps.Status = PwaCapabilityCheckStatus.Passed;
238+
return httpsCapabilities;
219239
}
220-
catch (Exception error)
240+
catch (Exception ex)
221241
{
222-
logger.LogError(error, "Error running Lighthouse audit for {url}", job.Url);
223-
return null;
242+
logger.LogError(ex, "Error detecting HTTPS capabilities for {url}", url);
243+
httpsCapabilities.ForEach(c => c.Status = PwaCapabilityCheckStatus.Skipped);
244+
return httpsCapabilities;
224245
}
225246
}
226247

apps/pwabuilder/Services/LighthouseService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace PWABuilder.Services;
99

10+
[Obsolete("LighthouseService shouldn't be used because Lighthouse 12 removed PWA audits. See https://github.com/GoogleChrome/lighthouse/blob/main/changelog.md#pwa-category-removal")]
1011
public class LighthouseService : ILighthouseService
1112
{
1213
private readonly IHostEnvironment env;
@@ -242,7 +243,7 @@ private static Process StartLighthouse(Uri url, BrowserFormFactor formFactor, in
242243
+ $"--output=json --output-path=stdout "
243244
+ $"--port={headlessChromePort} "
244245
+ $"--config-path=\"{lighthouseSettingsPath}\" "
245-
+ $"--only-audits=installable-manifest,is-on-https,service-worker-audit,https-audit,offline-audit,web-app-manifest-raw-audit "
246+
+ $"--only-audits=is-on-https " // Only check if the site is served over HTTPS
246247
+ $"--form-factor={(formFactor == BrowserFormFactor.Desktop ? "desktop" : "mobile")} "
247248
+ $"{(formFactor == BrowserFormFactor.Mobile ? "--screenEmulation.mobile " : string.Empty)}"
248249
+ $"--screenEmulation.width={viewport.Width} "

apps/pwabuilder/Services/ManifestAnalyzer.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,23 @@ public ManifestAnalyzer(IImageValidationService imageValidator)
2828
/// Goes through all the manifest-specific capabilities of the specified <paramref name="analysis"/> and checks if the manifest passes.
2929
/// </summary>
3030
/// <param name="manifestDetection">The web app manifest detection results. This can be null if no web app manifest was detect.</param>
31-
/// <param name="noManifestStatus">The status to assign to the "has manifest" capability if no manifest was detected.</param>
3231
/// <param name="cancelToken">The cancellation token.</param>
3332
/// <param name="logger">The logger to log data to.</param>
3433
/// <returns>A list of PWA capabilities and their statuses.</returns>
35-
public async Task<List<PwaCapability>> TryAnalyzeManifestAsync(ManifestDetection? manifestDetection, PwaCapabilityCheckStatus noManifestStatus, ILogger logger, CancellationToken cancelToken)
34+
public async Task<List<PwaCapability>> TryAnalyzeManifestAsync(ManifestDetection? manifestDetection, ILogger logger, CancellationToken cancelToken)
3635
{
3736
var manifestCapabilities = PwaCapability.CreateManifestCapabilities();
3837

39-
// No manifest? Mark all the manifest capabilities as skipped for now.
38+
// No manifest? Mark all the manifest capabilities as skipped.
4039
if (manifestDetection == null)
4140
{
4241
logger.LogInformation("No manifest to analyze. Skipping manifest capability checks.");
4342

44-
// Mark the "manifest exists" capability with the desired status..
43+
// Mark the "manifest exists" capability as failed.
4544
var manifestExistsCapability = manifestCapabilities.First(c => c.Id == PwaCapabilityId.HasManifest);
46-
manifestExistsCapability.Status = noManifestStatus;
45+
manifestExistsCapability.Status = PwaCapabilityCheckStatus.Failed;
4746

48-
// Mark all other manifest capabilities as skipped for now.
47+
// Mark all other manifest capabilities as skipped.
4948
manifestCapabilities
5049
.Except([manifestExistsCapability])
5150
.ToList()
@@ -147,7 +146,6 @@ private PwaManifestCapabilityCheck CreateCheckForCapability(PwaCapability capabi
147146

148147
// HTTPS capabilities are handled elsewhere.
149148
PwaCapabilityId.HasHttps => throw new NotImplementedException(),
150-
PwaCapabilityId.NoMixedContent => throw new NotImplementedException(),
151149

152150
// General capabilities are handled elsewhere.
153151
PwaCapabilityId.ServesHtml => throw new NotImplementedException()

apps/pwabuilder/Services/ManifestDetector.cs

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -42,43 +42,6 @@ public ManifestDetector(WebStringCache webStringCache, IPuppeteerService puppete
4242
return webManifest;
4343
}
4444

45-
/// <summary>
46-
/// Inspects a LighthouseReport and sees if it's possible to generate a ManifestDetection from it.
47-
/// </summary>
48-
/// <param name="report">The Lighthouse report.</param>
49-
/// <param name="logger">The logger.</param>
50-
/// <returns>A <see cref="ManifestDetection"/> if the Lighthouse report found a valid manifest, otherwise null.</returns>
51-
public ManifestDetection? TryDetectFromLighthouse(LighthouseReport? report, ILogger logger)
52-
{
53-
var manifestUrl = report?.WebAppManifestAudit?.Details?.ManifestUrl;
54-
var manifestRaw = report?.WebAppManifestAudit?.Details?.ManifestRaw;
55-
if (manifestUrl == null || manifestRaw == null || !Uri.TryCreate(manifestUrl, UriKind.Absolute, out var manifestUri))
56-
{
57-
return null;
58-
}
59-
60-
JsonElement manifest;
61-
try
62-
{
63-
manifest = JsonSerializer.Deserialize<JsonElement>(manifestRaw);
64-
}
65-
catch (Exception jsonParsingError)
66-
{
67-
logger.LogWarning(jsonParsingError, "Lighthouse report contained invalid JSON for the manifest at {manifestUrl}.", manifestUrl);
68-
return null;
69-
}
70-
71-
// Create a new ManifestDetection from the LighthouseReport
72-
var webManifest = new ManifestDetection
73-
{
74-
Url = manifestUri,
75-
ManifestRaw = manifestRaw,
76-
Manifest = manifest
77-
};
78-
79-
return webManifest;
80-
}
81-
8245
private async Task<ManifestDetection?> TryGetManifestFromPuppeteer(Uri appUrl, ILogger logger, CancellationToken cancelToken)
8346
{
8447
// Spin up a headless browser to find the manifest link.

apps/pwabuilder/Services/ServiceWorkerAnalyzer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ private PwaCapabilityCheckStatus RunCapabilityCheck(PwaCapability swCapability,
8787
return swCapability.Id switch
8888
{
8989
PwaCapabilityId.HasServiceWorker => swDetection != null ? PwaCapabilityCheckStatus.Passed : PwaCapabilityCheckStatus.Failed,
90-
PwaCapabilityId.OfflineSupport => PwaCapabilityCheckStatus.InProgress, // Offline support can't be detected from code analysis alone. Instead, we use Lighthouse for this. See LighthouseService.cs.
90+
PwaCapabilityId.OfflineSupport => PwaCapabilityCheckStatus.Failed, // TODO: implement offline check. We used to test this using Lighthouse, but they removed offline audit check as of Lighthouse v12.
9191
PwaCapabilityId.ServiceWorkerIsNotEmpty => CheckServiceWorkerNotEmpty(swScripts),
9292
PwaCapabilityId.BackgroundSync => CheckBackgroundSync(swScripts),
9393
PwaCapabilityId.PeriodicSync => CheckPeriodicSync(swScripts),

0 commit comments

Comments
 (0)