Skip to content

Commit 559dd83

Browse files
authored
Revert "feat: Add screenshot storage support to broken link checker (#123)"
This reverts commit cd34e35.
1 parent cd34e35 commit 559dd83

17 files changed

+581
-2210
lines changed

package-lock.json

Lines changed: 89 additions & 714 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/synthetics-sdk-broken-links/package.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,20 @@
2727
"@types/chai": "^4.3.4",
2828
"@types/express": "^4.17.17",
2929
"@types/node": "^18.15.10",
30-
"@types/proxyquire": "^1.3.31",
3130
"@types/sinon": "^10.0.16",
3231
"@types/supertest": "^2.0.12",
3332
"chai": "^4.3.7",
3433
"chai-exclude": "^2.1.0",
3534
"express": "^4.18.2",
36-
"proxyquire": "^2.1.3",
37-
"node-mocks-http": "^1.13.0",
38-
"sinon": "^16.1.1",
35+
"sinon": "^15.2.0",
3936
"supertest": "^6.3.3",
4037
"synthetics-sdk-broken-links": "file:./"
4138
},
4239
"engines": {
4340
"node": ">=18"
4441
},
4542
"dependencies": {
46-
"@google-cloud/storage": "^7.7.0",
47-
"@google-cloud/synthetics-sdk-api": "^0.6.0",
43+
"@google-cloud/synthetics-sdk-api": "^0.5.1",
4844
"puppeteer": "21.3.6"
4945
}
5046
}

packages/synthetics-sdk-broken-links/src/broken_links.ts

Lines changed: 22 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
// Internal Project Files
15+
import puppeteer, { Browser, Page } from 'puppeteer';
1616
import {
17-
BaseError,
1817
BrokenLinksResultV1_BrokenLinkCheckerOptions,
1918
BrokenLinksResultV1_SyntheticLinkResult,
20-
getRuntimeMetadata,
2119
instantiateMetadata,
20+
getRuntimeMetadata,
2221
SyntheticResult,
2322
} from '@google-cloud/synthetics-sdk-api';
2423
import {
@@ -33,19 +32,10 @@ import {
3332
checkLinks,
3433
closeBrowser,
3534
closePagePool,
36-
openNewPage,
3735
retrieveLinksFromPage,
36+
openNewPage,
3837
} from './navigation_func';
39-
import { processOptions } from './options_func';
40-
import {
41-
createStorageClientIfStorageSelected,
42-
getOrCreateStorageBucket,
43-
StorageParameters,
44-
} from './storage_func';
45-
46-
// External Dependencies
47-
import { Bucket } from '@google-cloud/storage';
48-
import puppeteer, { Browser, Page } from 'puppeteer';
38+
import { setDefaultOptions, validateInputOptions } from './options_func';
4939

5040
export interface BrokenLinkCheckerOptions {
5141
origin_uri: string;
@@ -58,7 +48,6 @@ export interface BrokenLinkCheckerOptions {
5848
wait_for_selector?: string;
5949
per_link_options?: { [key: string]: PerLinkOption };
6050
total_synthetic_timeout_millis?: number;
61-
screenshot_options?: ScreenshotOptions;
6251
}
6352

6453
export interface PerLinkOption {
@@ -81,17 +70,6 @@ export enum StatusClass {
8170
STATUS_CLASS_ANY = 'STATUS_CLASS_ANY',
8271
}
8372

84-
export interface ScreenshotOptions {
85-
storage_location?: string;
86-
capture_condition?: CaptureCondition;
87-
}
88-
89-
export enum CaptureCondition {
90-
NONE = 'NONE',
91-
FAILING = 'FAILING',
92-
ALL = 'ALL',
93-
}
94-
9573
let synthetics_sdk_broken_links_package;
9674
try {
9775
synthetics_sdk_broken_links_package = require('../package.json');
@@ -101,11 +79,7 @@ try {
10179
instantiateMetadata(synthetics_sdk_broken_links_package);
10280

10381
export async function runBrokenLinks(
104-
inputOptions: BrokenLinkCheckerOptions,
105-
args: {
106-
executionId: string | undefined;
107-
checkId: string | undefined;
108-
}
82+
inputOptions: BrokenLinkCheckerOptions
10983
): Promise<SyntheticResult> {
11084
// init
11185
const startTime = new Date().toISOString();
@@ -122,30 +96,6 @@ export async function runBrokenLinks(
12296
const [timeLimitPromise, timeLimitTimeout, timeLimitresolver] =
12397
getTimeLimitPromise(startTime, adjusted_synthetic_timeout_millis);
12498

125-
const errors: BaseError[] = [];
126-
127-
// Initialize Storage Client with Error Handling. Set to `null` if
128-
// capture_condition is 'None'
129-
const storageClient = createStorageClientIfStorageSelected(
130-
errors,
131-
options.screenshot_options!.capture_condition
132-
);
133-
134-
// // Bucket Validation
135-
const bucket: Bucket | null = await getOrCreateStorageBucket(
136-
storageClient,
137-
options.screenshot_options!.storage_location,
138-
errors
139-
);
140-
141-
const storageParams: StorageParameters = {
142-
storageClient: storageClient,
143-
bucket: bucket,
144-
checkId: args.checkId || '_',
145-
executionId: args.executionId || '_',
146-
screenshotNumber: 1,
147-
};
148-
14999
const followed_links: BrokenLinksResultV1_SyntheticLinkResult[] = [];
150100

151101
const checkLinksPromise = async () => {
@@ -159,8 +109,7 @@ export async function runBrokenLinks(
159109
originPage,
160110
options,
161111
startTime,
162-
adjusted_synthetic_timeout_millis,
163-
storageParams
112+
adjusted_synthetic_timeout_millis
164113
)
165114
);
166115

@@ -182,8 +131,7 @@ export async function runBrokenLinks(
182131
linksToFollow,
183132
options,
184133
startTime,
185-
adjusted_synthetic_timeout_millis,
186-
storageParams
134+
adjusted_synthetic_timeout_millis
187135
))
188136
);
189137
return true;
@@ -201,9 +149,7 @@ export async function runBrokenLinks(
201149
startTime,
202150
runtime_metadata,
203151
options,
204-
followed_links,
205-
storageParams,
206-
errors
152+
followed_links
207153
);
208154
} catch (err) {
209155
const errorMessage =
@@ -230,8 +176,7 @@ async function checkOriginLink(
230176
originPage: Page,
231177
options: BrokenLinksResultV1_BrokenLinkCheckerOptions,
232178
startTime: string,
233-
adjusted_synthetic_timeout_millis: number,
234-
storageParams: StorageParameters
179+
adjusted_synthetic_timeout_millis: number
235180
): Promise<BrokenLinksResultV1_SyntheticLinkResult> {
236181
let originLinkResult: BrokenLinksResultV1_SyntheticLinkResult;
237182

@@ -248,7 +193,6 @@ async function checkOriginLink(
248193
originPage,
249194
{ target_uri: options.origin_uri, anchor_text: '', html_element: '' },
250195
options,
251-
storageParams,
252196
true
253197
);
254198

@@ -319,3 +263,16 @@ async function scrapeLinks(
319263
options.link_order
320264
);
321265
}
266+
267+
/**
268+
* Validates input options and sets defaults in `options`.
269+
*
270+
* @param inputOptions - The input options for the broken link checker.
271+
* @returns The processed broken link checker options.
272+
*/
273+
function processOptions(
274+
inputOptions: BrokenLinkCheckerOptions
275+
): BrokenLinksResultV1_BrokenLinkCheckerOptions {
276+
const validOptions = validateInputOptions(inputOptions);
277+
return setDefaultOptions(validOptions);
278+
}

packages/synthetics-sdk-broken-links/src/handlers.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
// Standard Libraries
16-
import { Request, Response } from 'express';
17-
18-
// Internal Project Files
1915
import { runBrokenLinks, BrokenLinkCheckerOptions } from './broken_links';
20-
21-
const syntheticExecutionIdHeader = 'Synthetic-Execution-Id';
22-
const checkIdHeader = 'Check-Id';
16+
import { Request, Response } from 'express';
2317

2418
/**
2519
* Middleware for easy invocation of SyntheticSDK broken links, and may be used to
@@ -32,10 +26,5 @@ const checkIdHeader = 'Check-Id';
3226
export function runBrokenLinksHandler(options: BrokenLinkCheckerOptions) {
3327
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3428
return async (req: Request, res: Response): Promise<any> =>
35-
res.send(
36-
await runBrokenLinks(options, {
37-
executionId: req.get(syntheticExecutionIdHeader),
38-
checkId: req.get(checkIdHeader),
39-
})
40-
);
29+
res.send(await runBrokenLinks(options));
4130
}

packages/synthetics-sdk-broken-links/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
// limitations under the License.
1414

1515
export {
16+
runBrokenLinks,
1617
BrokenLinkCheckerOptions,
17-
LinkOrder,
1818
PerLinkOption,
19-
runBrokenLinks,
2019
StatusClass,
20+
LinkOrder,
2121
} from './broken_links';
2222
export * from './handlers';
2323
export * from '@google-cloud/synthetics-sdk-api';

packages/synthetics-sdk-broken-links/src/link_utils.ts

Lines changed: 2 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,11 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
// Standard Libraries
16-
import * as path from 'path';
17-
18-
// Internal Project Files
15+
import { HTTPResponse } from 'puppeteer';
1916
import {
20-
BaseError,
2117
BrokenLinksResultV1,
2218
BrokenLinksResultV1_BrokenLinkCheckerOptions,
2319
BrokenLinksResultV1_BrokenLinkCheckerOptions_LinkOrder,
24-
BrokenLinksResultV1_BrokenLinkCheckerOptions_ScreenshotOptions_CaptureCondition as ApiCaptureCondition,
2520
BrokenLinksResultV1_SyntheticLinkResult,
2621
GenericResultV1,
2722
getRuntimeMetadata,
@@ -30,10 +25,6 @@ import {
3025
SyntheticResult,
3126
} from '@google-cloud/synthetics-sdk-api';
3227

33-
// External Dependencies
34-
import { HTTPResponse } from 'puppeteer';
35-
import { StorageParameters } from './storage_func';
36-
3728
/**
3829
* Represents an intermediate link with its properties.
3930
*/
@@ -162,8 +153,6 @@ function parseFollowedLinks(
162153
options: {} as BrokenLinksResultV1_BrokenLinkCheckerOptions,
163154
origin_link_result: {} as BrokenLinksResultV1_SyntheticLinkResult,
164155
followed_link_results: [],
165-
execution_data_storage_path: '',
166-
errors: [],
167156
};
168157

169158
for (const link of followed_links) {
@@ -227,21 +216,12 @@ export function createSyntheticResult(
227216
start_time: string,
228217
runtime_metadata: { [key: string]: string },
229218
options: BrokenLinksResultV1_BrokenLinkCheckerOptions,
230-
followed_links: BrokenLinksResultV1_SyntheticLinkResult[],
231-
storageParams: StorageParameters,
232-
errors: BaseError[]
219+
followed_links: BrokenLinksResultV1_SyntheticLinkResult[]
233220
): SyntheticResult {
234221
// Create BrokenLinksResultV1 by parsing followed links and setting options
235222
const broken_links_result: BrokenLinksResultV1 =
236223
parseFollowedLinks(followed_links);
237224
broken_links_result.options = options;
238-
broken_links_result.errors = errors;
239-
broken_links_result.execution_data_storage_path = storageParams.bucket
240-
? 'gs://' +
241-
storageParams.bucket.name +
242-
'/' +
243-
getStoragePathToExecution(storageParams, options)
244-
: '';
245225

246226
// Create SyntheticResult object
247227
const synthetic_result: SyntheticResult = {
@@ -284,89 +264,6 @@ export function shuffleAndTruncate(
284264
return linksToFollow.slice(0, link_limit! - 1);
285265
}
286266

287-
/**
288-
* Determines whether a screenshot should be taken based on screenshot options and link result.
289-
*
290-
* @param options - BrokenLinksResultV1_BrokenLinkCheckerOptions
291-
* @param passed - boolean indicating whether the link navigation succeeded
292-
* @returns true if a screenshot should be taken, false otherwise
293-
*/
294-
export function shouldTakeScreenshot(
295-
options: BrokenLinksResultV1_BrokenLinkCheckerOptions,
296-
passed: boolean
297-
): boolean {
298-
return (
299-
options.screenshot_options!.capture_condition === ApiCaptureCondition.ALL ||
300-
(options.screenshot_options!.capture_condition ===
301-
ApiCaptureCondition.FAILING &&
302-
!passed)
303-
);
304-
}
305-
306-
/**
307-
308-
* Sanitizes an object name string for safe use, ensuring compliance with
309-
* naming restrictions.
310-
*
311-
* @param {string} inputString - The original object name string.
312-
* @returns {string} The sanitized object name.
313-
*
314-
* **Sanitization Rules:**
315-
* * Removes control characters ([\u007F-\u009F]).
316-
* * Removes disallowed characters (#, [, ], *, ?, ", <, >, |, /).
317-
* * Replaces the forbidden prefix ".well-known/acme-challenge/" with an underscore.
318-
* * Replaces standalone occurrences of "." or ".." with an underscore.
319-
*/
320-
export function sanitizeObjectName(
321-
inputString: string | null | undefined
322-
): string {
323-
if (!inputString || inputString === '.' || inputString === '..') return '_';
324-
325-
// Regular expressions for:
326-
/*eslint no-useless-escape: "off"*/
327-
const invalidCharactersRegex = /[\r\n\u007F-\u009F#\[\]*?:"<>|/]/g; // Control characters, special characters, path separator
328-
const wellKnownPrefixRegex = /^\.well-known\/acme-challenge\//;
329-
330-
// Core sanitization:
331-
return inputString
332-
.replace(wellKnownPrefixRegex, '_') // Replace forbidden prefix
333-
.replace(invalidCharactersRegex, '_') // replace invalid characters
334-
.trim() // Clean up any leading/trailing spaces
335-
.replace(/\s+/g, '_'); // Replace one or more spaces with underscores
336-
}
337-
338-
export function getStoragePathToExecution(
339-
storageParams: StorageParameters,
340-
options: BrokenLinksResultV1_BrokenLinkCheckerOptions
341-
) {
342-
try {
343-
const storageLocation = options.screenshot_options!.storage_location;
344-
let writeDestination = '';
345-
346-
// extract folder name for a given storage location. If there is no '/'
347-
// present then the storageLocation is just a folder
348-
const firstSlashIndex = storageLocation.indexOf('/');
349-
if (firstSlashIndex !== -1) {
350-
writeDestination = storageLocation.substring(firstSlashIndex + 1);
351-
}
352-
353-
// Ensure writeDestination ends with a slash for proper path joining
354-
if (writeDestination && !writeDestination.endsWith('/')) {
355-
writeDestination += '/';
356-
}
357-
358-
writeDestination = path.join(
359-
writeDestination,
360-
storageParams.checkId,
361-
storageParams.executionId
362-
);
363-
364-
return writeDestination;
365-
} catch (err) {
366-
return '';
367-
}
368-
}
369-
370267
export function getTimeLimitPromise(
371268
startTime: string,
372269
totalTimeoutMillis: number,

0 commit comments

Comments
 (0)