import { ICrusherSDKElement } from "@crusher-shared/types/sdk/element" ; import { ICrusherSdk } from "@crusher-shared/types/sdk/sdk" ; import { CrusherCookieSetPayload } from "@crusher-shared/types/sdk/types" ; import { Page } from "playwright" ; import { ExportsManager } from "../functions/exports" ; import { CrusherElementSdk } from "./element" ; import { StorageManager } from "../functions/storage" ; import { chunkArray , markTestFail } from "../utils/helper" ; import nodeFetch from "node-fetch" ; import https from "https" ; const pageScreenshotModule = require ( "../actions/pageScreenshot" ) ; class CrusherSdk implements ICrusherSdk { page : Page ; exportsManager : ExportsManager ; storageManager : StorageManager ; constructor ( page , exportsManager , storageManager ) { this . page = page ; this . exportsManager = exportsManager ; this . storageManager = storageManager ; } async $ ( selector ) { const elementHandle = await this . page . $ ( selector ) ; return new CrusherElementSdk ( this . page , elementHandle ) ; } async $nodeWrapper ( ) { } async goto ( url ) { return this . page . goto ( url ) ; } async reloadPage ( ) { await this . page . reload ( { waitUntil : "networkidle" } ) ; return true ; } async sleep ( timeout ) { return new Promise ( ( resolve ) => { setTimeout ( ( ) => resolve ( true ) , timeout ) ; } ) ; } async setCookies ( cookies ) { const finalCookies = cookies . map ( ( cookie ) => { return { ... cookie , url : undefined , } ; } ) ; await this . page . context ( ) . addCookies ( finalCookies ) ; return true ; } async fetch ( url , options ) { await this . page . evaluate ( ( [ url , options ] ) => { return fetch ( url , options ) ; } , [ url , options ] ) ; return true ; } takePageScreenshot ( ) { return pageScreenshotModule . handler ( this . page , null , null , this . storageManager ) ; } setExport ( key , value ) { return this . exportsManager . set ( key , value ) ; } getExport ( key ) { return this . exportsManager . get ( key ) ; } hasExport ( key ) { return this . exportsManager . has ( key ) ; } private async urlExist ( url ) { const agent = new https . Agent ( { rejectUnauthorized : false , } ) ; return nodeFetch ( url , { method : "HEAD" , redirect : "follow" , agent : agent } ) . then ( async ( res ) => { const allowedMethods = res . headers . get ( "allow" ) ; if ( allowedMethods && ! allowedMethods . includes ( "HEAD" ) && allowedMethods . includes ( "GET" ) ) { return nodeFetch ( url , { method : "GET" , redirect : "follow" , agent : agent } ) . then ( async ( res ) => { return ! ! res . ok ; } ) ; } return ! ! res . ok ; } ) ; } async verifyLinks ( links ) { const chunkedArr = chunkArray ( links , 5 ) ; const promises = chunkedArr . map ( ( chunk ) => { return Promise . all ( chunk . map ( async ( link ) => { let reason = null , exists = null ; try { exists = await this . urlExist ( link . href ) ; } catch ( ex ) { exists = false ; reason = ex . message ; } return { href : link . href , exists , reason } ; } ) ) ; } ) ; const result = [ ] ; for ( let promise of promises ) { const values = await promise ; values . forEach ( ( value ) => { result . push ( value ) ; } ) ; } return result ; } markTestFail ( reason , data ) { markTestFail ( reason , data ) ; } } export { CrusherSdk } ;