Best JavaScript code snippet using playwright-internal
injectedScriptSource.js
Source:injectedScriptSource.js
...2772 parseSelector(e) {2773 const t = (0, s.parseSelector)(e)2774 for (const n of t.parts)2775 if (!this._engines.has(n.name))2776 throw this.createStacklessError(2777 `Unknown engine "${n.name}" while parsing selector ${e}`2778 )2779 return t2780 }2781 querySelector(e, t, n) {2782 if (!t.querySelector)2783 throw this.createStacklessError('Node is not queryable.')2784 this._evaluator.begin()2785 try {2786 var r, o2787 const i = this._querySelectorRecursively(2788 [{ element: t, capture: void 0 }],2789 e,2790 0,2791 new Map()2792 )2793 if (n && i.length > 1)2794 throw this.strictModeViolationError(2795 e,2796 i.map((e) => e.element)2797 )2798 return (2799 (null === (r = i[0]) || void 0 === r ? void 0 : r.capture) ||2800 (null === (o = i[0]) || void 0 === o ? void 0 : o.element)2801 )2802 } finally {2803 this._evaluator.end()2804 }2805 }2806 _querySelectorRecursively(e, t, n, r) {2807 if (n === t.parts.length) return e2808 const o = t.parts[n]2809 if ('nth' === o.name) {2810 let i = []2811 if ('0' === o.body) i = e.slice(0, 1)2812 else if ('-1' === o.body) e.length && (i = e.slice(e.length - 1))2813 else {2814 if ('number' == typeof t.capture)2815 throw this.createStacklessError(2816 "Can't query n-th element in a request with the capture."2817 )2818 const n = +o.body,2819 r = new Set()2820 for (const t of e) r.add(t.element), n + 1 === r.size && (i = [t])2821 }2822 return this._querySelectorRecursively(i, t, n + 1, r)2823 }2824 if ('visible' === o.name) {2825 const i = Boolean(o.body),2826 s = e.filter((e) => i === (0, c.isVisible)(e.element))2827 return this._querySelectorRecursively(s, t, n + 1, r)2828 }2829 const i = []2830 for (const o of e) {2831 const e = n - 1 === t.capture ? o.element : o.capture2832 let s = r.get(o.element)2833 s || ((s = []), r.set(o.element, s))2834 let c = s[n]2835 c || ((c = this._queryEngineAll(t.parts[n], o.element)), (s[n] = c))2836 for (const t of c) {2837 if (!('nodeName' in t))2838 throw this.createStacklessError(2839 `Expected a Node but got ${Object.prototype.toString.call(t)}`2840 )2841 i.push({ element: t, capture: e })2842 }2843 }2844 return this._querySelectorRecursively(i, t, n + 1, r)2845 }2846 querySelectorAll(e, t) {2847 if (!t.querySelectorAll)2848 throw this.createStacklessError('Node is not queryable.')2849 this._evaluator.begin()2850 try {2851 const n = this._querySelectorRecursively(2852 [{ element: t, capture: void 0 }],2853 e,2854 0,2855 new Map()2856 ),2857 r = new Set()2858 for (const e of n) r.add(e.capture || e.element)2859 return [...r]2860 } finally {2861 this._evaluator.end()2862 }2863 }2864 _queryEngineAll(e, t) {2865 return this._engines.get(e.name).queryAll(t, e.body)2866 }2867 _createAttributeEngine(e, t) {2868 return {2869 queryAll: (n, r) =>2870 this._evaluator.query(2871 { scope: n, pierceShadow: t },2872 ((t) => [2873 {2874 simples: [2875 {2876 selector: {2877 css: `[${e}=${JSON.stringify(t)}]`,2878 functions: []2879 },2880 combinator: ''2881 }2882 ]2883 }2884 ])(r)2885 )2886 }2887 }2888 _createCSSEngine() {2889 const e = this._evaluator2890 return {2891 queryAll: (t, n) => e.query({ scope: t, pierceShadow: !0 }, n)2892 }2893 }2894 _createTextEngine(e) {2895 const t = (t, n) => {2896 const { matcher: r, kind: o } = (function (e) {2897 if ('/' === e[0] && e.lastIndexOf('/') > 0) {2898 const t = e.lastIndexOf('/')2899 return {2900 matcher: (0, c.createRegexTextMatcher)(2901 e.substring(1, t),2902 e.substring(t + 1)2903 ),2904 kind: 'regex'2905 }2906 }2907 let t = !12908 return (2909 e.length > 1 &&2910 '"' === e[0] &&2911 '"' === e[e.length - 1] &&2912 ((e = f(e.substring(1, e.length - 1))), (t = !0)),2913 e.length > 1 &&2914 "'" === e[0] &&2915 "'" === e[e.length - 1] &&2916 ((e = f(e.substring(1, e.length - 1))), (t = !0)),2917 {2918 matcher: t2919 ? (0, c.createStrictTextMatcher)(e)2920 : (0, c.createLaxTextMatcher)(e),2921 kind: t ? 'strict' : 'lax'2922 }2923 )2924 })(n),2925 i = []2926 let s = null2927 const a = (e) => {2928 if ('lax' === o && s && s.contains(e)) return !12929 const t = (0, c.elementMatchesText)(this._evaluator, e, r)2930 'none' === t && (s = e),2931 ('self' === t || ('selfAndChildren' === t && 'strict' === o)) &&2932 i.push(e)2933 }2934 t.nodeType === Node.ELEMENT_NODE && a(t)2935 const u = this._evaluator._queryCSS(2936 { scope: t, pierceShadow: e },2937 '*'2938 )2939 for (const e of u) a(e)2940 return i2941 }2942 return { queryAll: (e, n) => t(e, n) }2943 }2944 extend(e, t) {2945 return new (n.g.eval(2946 `\n (() => {\n ${e}\n return pwExport;\n })()`2947 ))(this, t)2948 }2949 isVisible(e) {2950 return (0, c.isVisible)(e)2951 }2952 pollRaf(e) {2953 return this.poll(e, (e) => requestAnimationFrame(e))2954 }2955 pollInterval(e, t) {2956 return this.poll(t, (t) => setTimeout(t, e))2957 }2958 pollLogScale(e) {2959 const t = [100, 250, 500]2960 let n = 02961 return this.poll(e, (e) => setTimeout(e, t[n++] || 1e3))2962 }2963 poll(e, t) {2964 return this._runAbortableTask((n) => {2965 let r, o2966 const i = new Promise((e, t) => {2967 ;(r = e), (o = t)2968 }),2969 s = () => {2970 if (!n.aborted)2971 try {2972 const o = e(n)2973 o !== n.continuePolling ? r(o) : t(s)2974 } catch (e) {2975 n.log(' ' + e.message), o(e)2976 }2977 }2978 return s(), i2979 })2980 }2981 _runAbortableTask(e) {2982 let t,2983 n = [],2984 r = !12985 const o = () => {2986 t && (t(n), (n = []), (t = void 0))2987 }2988 let i,2989 s = ''2990 const c = {2991 injectedScript: this,2992 aborted: !1,2993 continuePolling: Symbol('continuePolling'),2994 log: (e) => {2995 ;(s = e), n.push({ message: e }), o()2996 },2997 logRepeating: (e) => {2998 e !== s && c.log(e)2999 },3000 setIntermediateResult: (e) => {3001 i !== e && ((i = e), n.push({ intermediateResult: e }), o())3002 }3003 }3004 return {3005 takeNextLogs: () =>3006 new Promise((e) => {3007 ;(t = e), (n.length || r) && o()3008 }),3009 run: () => {3010 const t = e(c)3011 return (3012 t.finally(() => {3013 ;(r = !0), o()3014 }),3015 t3016 )3017 },3018 cancel: () => {3019 c.aborted = !03020 },3021 takeLastLogs: () => n3022 }3023 }3024 getElementBorderWidth(e) {3025 if (3026 e.nodeType !== Node.ELEMENT_NODE ||3027 !e.ownerDocument ||3028 !e.ownerDocument.defaultView3029 )3030 return { left: 0, top: 0 }3031 const t = e.ownerDocument.defaultView.getComputedStyle(e)3032 return {3033 left: parseInt(t.borderLeftWidth || '', 10),3034 top: parseInt(t.borderTopWidth || '', 10)3035 }3036 }3037 retarget(e, t) {3038 let n = e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement3039 return n3040 ? (n.matches('input, textarea, select') ||3041 (n =3042 n.closest(3043 'button, [role=button], [role=checkbox], [role=radio]'3044 ) || n),3045 'follow-label' === t &&3046 (n.matches(3047 'input, textarea, button, select, [role=button], [role=checkbox], [role=radio]'3048 ) ||3049 n.isContentEditable ||3050 (n = n.closest('label') || n),3051 'LABEL' === n.nodeName && (n = n.control || n)),3052 n)3053 : null3054 }3055 waitForElementStatesAndPerformAction(e, t, n, r) {3056 let o,3057 i = 0,3058 s = 0,3059 c = 03060 return this.pollRaf((a) => {3061 if (n) return a.log(' forcing action'), r(e, a)3062 for (const n of t) {3063 if ('stable' !== n) {3064 const t = this.elementState(e, n)3065 if ('boolean' != typeof t) return t3066 if (!t)3067 return (3068 a.logRepeating(` element is not ${n} - waiting...`),3069 a.continuePolling3070 )3071 continue3072 }3073 const t = this.retarget(e, 'no-follow-label')3074 if (!t) return 'error:notconnected'3075 if (1 == ++i) return a.continuePolling3076 const r = performance.now()3077 if (this._stableRafCount > 1 && r - c < 15) return a.continuePolling3078 c = r3079 const u = t.getBoundingClientRect(),3080 l = { x: u.top, y: u.left, width: u.width, height: u.height }3081 o &&3082 l.x === o.x &&3083 l.y === o.y &&3084 l.width === o.width &&3085 l.height === o.height3086 ? ++s3087 : (s = 0)3088 const h = s >= this._stableRafCount,3089 p = h || !o3090 if (3091 ((o = l),3092 p || a.logRepeating(' element is not stable - waiting...'),3093 !h)3094 )3095 return a.continuePolling3096 }3097 return r(e, a)3098 })3099 }3100 elementState(e, t) {3101 const n = this.retarget(3102 e,3103 ['stable', 'visible', 'hidden'].includes(t)3104 ? 'no-follow-label'3105 : 'follow-label'3106 )3107 if (!n || !n.isConnected) return 'hidden' === t || 'error:notconnected'3108 if ('visible' === t) return this.isVisible(n)3109 if ('hidden' === t) return !this.isVisible(n)3110 const r =3111 ['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA'].includes(n.nodeName) &&3112 n.hasAttribute('disabled')3113 if ('disabled' === t) return r3114 if ('enabled' === t) return !r3115 const o = !(3116 ['INPUT', 'TEXTAREA', 'SELECT'].includes(n.nodeName) &&3117 n.hasAttribute('readonly')3118 )3119 if ('editable' === t) return !r && o3120 if ('checked' === t) {3121 if (['checkbox', 'radio'].includes(n.getAttribute('role') || ''))3122 return 'true' === n.getAttribute('aria-checked')3123 if ('INPUT' !== n.nodeName)3124 throw this.createStacklessError('Not a checkbox or radio button')3125 if (!['radio', 'checkbox'].includes(n.type.toLowerCase()))3126 throw this.createStacklessError('Not a checkbox or radio button')3127 return n.checked3128 }3129 throw this.createStacklessError(`Unexpected element state "${t}"`)3130 }3131 selectOptions(e, t, n) {3132 const r = this.retarget(t, 'follow-label')3133 if (!r) return 'error:notconnected'3134 if ('select' !== r.nodeName.toLowerCase())3135 throw this.createStacklessError('Element is not a <select> element')3136 const o = r,3137 i = [...o.options],3138 s = []3139 let c = e.slice()3140 for (let e = 0; e < i.length; e++) {3141 const t = i[e],3142 n = (n) => {3143 if (n instanceof Node) return t === n3144 let r = !03145 return (3146 void 0 !== n.value && (r = r && n.value === t.value),3147 void 0 !== n.label && (r = r && n.label === t.label),3148 void 0 !== n.index && (r = r && n.index === e),3149 r3150 )3151 }3152 if (c.some(n)) {3153 if ((s.push(t), !o.multiple)) {3154 c = []3155 break3156 }3157 c = c.filter((e) => !n(e))3158 }3159 }3160 return c.length3161 ? (n.logRepeating(' did not find some options - waiting... '),3162 n.continuePolling)3163 : ((o.value = void 0),3164 s.forEach((e) => (e.selected = !0)),3165 n.log(' selected specified option(s)'),3166 o.dispatchEvent(new Event('input', { bubbles: !0 })),3167 o.dispatchEvent(new Event('change', { bubbles: !0 })),3168 s.map((e) => e.value))3169 }3170 fill(e, t, n) {3171 const r = this.retarget(t, 'follow-label')3172 if (!r) return 'error:notconnected'3173 if ('input' === r.nodeName.toLowerCase()) {3174 const t = r,3175 o = t.type.toLowerCase(),3176 i = new Set([3177 'date',3178 'time',3179 'datetime',3180 'datetime-local',3181 'month',3182 'week'3183 ])3184 if (3185 !new Set([3186 '',3187 'email',3188 'number',3189 'password',3190 'search',3191 'tel',3192 'text',3193 'url'3194 ]).has(o) &&3195 !i.has(o)3196 )3197 throw (3198 (n.log(` input of type "${o}" cannot be filled`),3199 this.createStacklessError(3200 `Input of type "${o}" cannot be filled`3201 ))3202 )3203 if ('number' === o && ((e = e.trim()), isNaN(Number(e))))3204 throw this.createStacklessError(3205 'Cannot type text into input[type=number]'3206 )3207 if (i.has(o)) {3208 if (((e = e.trim()), t.focus(), (t.value = e), t.value !== e))3209 throw this.createStacklessError('Malformed value')3210 return (3211 r.dispatchEvent(new Event('input', { bubbles: !0 })),3212 r.dispatchEvent(new Event('change', { bubbles: !0 })),3213 'done'3214 )3215 }3216 } else if ('textarea' === r.nodeName.toLowerCase());3217 else if (!r.isContentEditable)3218 throw this.createStacklessError(3219 'Element is not an <input>, <textarea> or [contenteditable] element'3220 )3221 return this.selectText(r), 'needsinput'3222 }3223 selectText(e) {3224 const t = this.retarget(e, 'follow-label')3225 if (!t) return 'error:notconnected'3226 if ('input' === t.nodeName.toLowerCase()) {3227 const e = t3228 return e.select(), e.focus(), 'done'3229 }3230 if ('textarea' === t.nodeName.toLowerCase()) {3231 const e = t3232 return (3233 (e.selectionStart = 0),3234 (e.selectionEnd = e.value.length),3235 e.focus(),3236 'done'3237 )3238 }3239 const n = t.ownerDocument.createRange()3240 n.selectNodeContents(t)3241 const r = t.ownerDocument.defaultView.getSelection()3242 return r && (r.removeAllRanges(), r.addRange(n)), t.focus(), 'done'3243 }3244 focusNode(e, t) {3245 if (!e.isConnected) return 'error:notconnected'3246 if (e.nodeType !== Node.ELEMENT_NODE)3247 throw this.createStacklessError('Node is not an element')3248 const n =3249 e.getRootNode().activeElement === e &&3250 e.ownerDocument &&3251 e.ownerDocument.hasFocus()3252 if ((e.focus(), t && !n && 'input' === e.nodeName.toLowerCase()))3253 try {3254 e.setSelectionRange(0, 0)3255 } catch (e) {}3256 return 'done'3257 }3258 setInputFiles(e, t) {3259 if (e.nodeType !== Node.ELEMENT_NODE)3260 return 'Node is not of type HTMLElement'3261 const n = e3262 if ('INPUT' !== n.nodeName) return 'Not an <input> element'3263 const r = n3264 if ('file' !== (r.getAttribute('type') || '').toLowerCase())3265 return 'Not an input[type=file] element'3266 const o = t.map((e) => {3267 const t = Uint8Array.from(atob(e.buffer), (e) => e.charCodeAt(0))3268 return new File([t], e.name, { type: e.mimeType })3269 }),3270 i = new DataTransfer()3271 for (const e of o) i.items.add(e)3272 ;(r.files = i.files),3273 r.dispatchEvent(new Event('input', { bubbles: !0 })),3274 r.dispatchEvent(new Event('change', { bubbles: !0 }))3275 }3276 checkHitTargetAt(e, t) {3277 let n = e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement3278 if (!n || !n.isConnected) return 'error:notconnected'3279 n = n.closest('button, [role=button]') || n3280 let r = this.deepElementFromPoint(document, t.x, t.y)3281 const o = []3282 for (; r && r !== n; )3283 o.push(r), (r = (0, c.parentElementOrShadowHost)(r))3284 if (r === n) return 'done'3285 const i = this.previewNode(o[0])3286 let s3287 for (; n; ) {3288 const e = o.indexOf(n)3289 if (-1 !== e) {3290 e > 1 && (s = this.previewNode(o[e - 1]))3291 break3292 }3293 n = (0, c.parentElementOrShadowHost)(n)3294 }3295 return s3296 ? { hitTargetDescription: `${i} from ${s} subtree` }3297 : { hitTargetDescription: i }3298 }3299 dispatchEvent(e, t, n) {3300 let r3301 switch (3302 ((n = { bubbles: !0, cancelable: !0, composed: !0, ...n }), p.get(t))3303 ) {3304 case 'mouse':3305 r = new MouseEvent(t, n)3306 break3307 case 'keyboard':3308 r = new KeyboardEvent(t, n)3309 break3310 case 'touch':3311 r = new TouchEvent(t, n)3312 break3313 case 'pointer':3314 r = new PointerEvent(t, n)3315 break3316 case 'focus':3317 r = new FocusEvent(t, n)3318 break3319 case 'drag':3320 r = new DragEvent(t, n)3321 break3322 default:3323 r = new Event(t, n)3324 }3325 e.dispatchEvent(r)3326 }3327 deepElementFromPoint(e, t, n) {3328 let r,3329 o = e3330 for (; o; ) {3331 const e = o.elementsFromPoint(t, n)[0]3332 if (!e || r === e) break3333 ;(r = e), (o = r.shadowRoot)3334 }3335 return r3336 }3337 previewNode(e) {3338 if (e.nodeType === Node.TEXT_NODE)3339 return h(`#text=${e.nodeValue || ''}`)3340 if (e.nodeType !== Node.ELEMENT_NODE)3341 return h(`<${e.nodeName.toLowerCase()} />`)3342 const t = e,3343 n = []3344 for (let e = 0; e < t.attributes.length; e++) {3345 const { name: r, value: o } = t.attributes[e]3346 'style' === r ||3347 r.startsWith('__playwright') ||3348 (!o && l.has(r) ? n.push(` ${r}`) : n.push(` ${r}="${o}"`))3349 }3350 n.sort((e, t) => e.length - t.length)3351 let r = n.join('')3352 if (3353 (r.length > 50 && (r = r.substring(0, 49) + 'â¦'), u.has(t.nodeName))3354 )3355 return h(`<${t.nodeName.toLowerCase()}${r}/>`)3356 const o = t.childNodes3357 let i = !13358 if (o.length <= 5) {3359 i = !03360 for (let e = 0; e < o.length; e++)3361 i = i && o[e].nodeType === Node.TEXT_NODE3362 }3363 let s = i ? t.textContent || '' : o.length ? 'â¦' : ''3364 return (3365 s.length > 50 && (s = s.substring(0, 49) + 'â¦'),3366 h(3367 `<${t.nodeName.toLowerCase()}${r}>${s}</${t.nodeName.toLowerCase()}>`3368 )3369 )3370 }3371 strictModeViolationError(e, t) {3372 const n = t3373 .slice(0, 10)3374 .map((e) => ({3375 preview: this.previewNode(e),3376 selector: (0, a.generateSelector)(this, e).selector3377 })),3378 r = n.map(3379 (e, t) =>3380 `\n ${t + 1}) ${e.preview} aka playwright.$("${e.selector}")`3381 )3382 return (3383 n.length < t.length && r.push('\n ...'),3384 this.createStacklessError(3385 `strict mode violation: "${e.selector}" resolved to ${3386 t.length3387 } elements:${r.join('')}\n`3388 )3389 )3390 }3391 createStacklessError(e) {3392 if ('firefox' === this._browserName) {3393 const t = new Error('Error: ' + e)3394 return (t.stack = ''), t3395 }3396 const t = new Error(e)3397 return delete t.stack, t3398 }3399 _setupGlobalListenersRemovalDetection() {3400 const e = '__playwright_global_listeners_check__'3401 let t = !13402 const n = () => (t = !0)3403 window.addEventListener(e, n),3404 new MutationObserver((r) => {3405 if (3406 r.some((e) =>3407 Array.from(e.addedNodes).includes(document.documentElement)3408 ) &&3409 ((t = !1), window.dispatchEvent(new CustomEvent(e)), !t)3410 ) {3411 window.addEventListener(e, n)3412 for (const e of this.onGlobalListenersRemoved) e()3413 }3414 }).observe(document, { childList: !0 })3415 }3416 expectSingleElement(e, t, n) {3417 const r = e.injectedScript,3418 o = n.expression3419 {3420 let n3421 if ('to.be.checked' === o)3422 n = e.injectedScript.elementState(t, 'checked')3423 else if ('to.be.disabled' === o)3424 n = e.injectedScript.elementState(t, 'disabled')3425 else if ('to.be.editable' === o)3426 n = e.injectedScript.elementState(t, 'editable')3427 else if ('to.be.empty' === o) {3428 var i3429 n =3430 'INPUT' === t.nodeName || 'TEXTAREA' === t.nodeName3431 ? !t.value3432 : !(null !== (i = t.textContent) && void 0 !== i && i.trim())3433 } else3434 'to.be.enabled' === o3435 ? (n = e.injectedScript.elementState(t, 'enabled'))3436 : 'to.be.focused' === o3437 ? (n = document.activeElement === t)3438 : 'to.be.hidden' === o3439 ? (n = e.injectedScript.elementState(t, 'hidden'))3440 : 'to.be.visible' === o &&3441 (n = e.injectedScript.elementState(t, 'visible'))3442 if (void 0 !== n) {3443 if ('error:notcheckbox' === n)3444 throw r.createStacklessError('Element is not a checkbox')3445 if ('error:notconnected' === n)3446 throw r.createStacklessError('Element is not connected')3447 return { received: n, matches: n }3448 }3449 }3450 if ('to.have.property' === o) {3451 const e = t[n.expressionArg]3452 return { received: e, matches: m(e, n.expectedValue) }3453 }3454 {3455 let e3456 if ('to.have.attribute' === o)3457 e = t.getAttribute(n.expressionArg) || ''3458 else if ('to.have.class' === o) e = t.className3459 else if ('to.have.css' === o)3460 e = window.getComputedStyle(t)[n.expressionArg]3461 else if ('to.have.id' === o) e = t.id3462 else if ('to.have.text' === o)3463 e = n.useInnerText ? t.innerText : t.textContent || ''3464 else if ('to.have.title' === o) e = document.title3465 else if ('to.have.url' === o) e = document.location.href3466 else if ('to.have.value' === o) {3467 if (3468 'INPUT' !== t.nodeName &&3469 'TEXTAREA' !== t.nodeName &&3470 'SELECT' !== t.nodeName3471 )3472 throw this.createStacklessError('Not an input element')3473 e = t.value3474 }3475 if (void 0 !== e && n.expectedText)3476 return { received: e, matches: new d(n.expectedText[0]).matches(e) }3477 }3478 throw this.createStacklessError('Unknown expect matcher: ' + o)3479 }3480 expectArray(e, t) {3481 const n = t.expression3482 if ('to.have.count' === n) {3483 const n = e.length3484 return { received: n, matches: n === t.expectedNumber }3485 }3486 let r3487 if (3488 ('to.have.text.array' === n || 'to.contain.text.array' === n3489 ? (r = e.map((e) =>3490 t.useInnerText ? e.innerText : e.textContent || ''3491 ))3492 : 'to.have.class.array' === n && (r = e.map((e) => e.className)),3493 r && t.expectedText)3494 ) {3495 const e = 'to.contain.text.array' !== n3496 if (r.length !== t.expectedText.length && e)3497 return { received: r, matches: !1 }3498 let o = 03499 const i = t.expectedText.map((e) => new d(e))3500 let s = !03501 for (const e of i) {3502 for (; o < r.length && !e.matches(r[o]); ) o++3503 if (o >= r.length) {3504 s = !13505 break3506 }3507 }3508 return { received: r, matches: s }3509 }3510 throw this.createStacklessError('Unknown expect matcher: ' + n)3511 }3512 }3513 e.default = g3514 })(),3515 (pwExport = r.default)...
frames.js
Source:frames.js
...852 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => element.textContent, undefined, options);853 }854 async innerText(metadata, selector, options = {}) {855 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => {856 if (element.namespaceURI !== 'http://www.w3.org/1999/xhtml') throw progress.injectedScript.createStacklessError('Node is not an HTMLElement');857 return element.innerText;858 }, undefined, options);859 }860 async innerHTML(metadata, selector, options = {}) {861 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => element.innerHTML, undefined, options);862 }863 async getAttribute(metadata, selector, name, options = {}) {864 return this._scheduleRerunnableTask(metadata, selector, (progress, element, data) => element.getAttribute(data.name), {865 name866 }, options);867 }868 async inputValue(metadata, selector, options = {}) {869 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => {870 if (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA' && element.nodeName !== 'SELECT') throw progress.injectedScript.createStacklessError('Node is not an <input>, <textarea> or <select> element');871 return element.value;872 }, undefined, options);873 }874 async _elementState(metadata, selector, state, options = {}) {875 const result = await this._scheduleRerunnableTask(metadata, selector, (progress, element, data) => {876 const injected = progress.injectedScript;877 return injected.elementState(element, data.state);878 }, {879 state880 }, options);881 return dom.throwRetargetableDOMError(result);882 }883 async isVisible(metadata, selector, options = {}) {884 const controller = new _progress.ProgressController(metadata, this);...
dom.js
Source:dom.js
...165 return this._page._delegate.getContentFrame(this);166 }167 async getAttribute(name) {168 return throwRetargetableDOMError(await this.evaluateInUtility(([injected, node, name]) => {169 if (node.nodeType !== Node.ELEMENT_NODE) throw injected.createStacklessError('Node is not an element');170 const element = node;171 return {172 value: element.getAttribute(name)173 };174 }, name)).value;175 }176 async inputValue() {177 return throwRetargetableDOMError(await this.evaluateInUtility(([injected, node]) => {178 if (node.nodeType !== Node.ELEMENT_NODE || node.nodeName !== 'INPUT' && node.nodeName !== 'TEXTAREA' && node.nodeName !== 'SELECT') throw injected.createStacklessError('Node is not an <input>, <textarea> or <select> element');179 const element = node;180 return {181 value: element.value182 };183 }, undefined)).value;184 }185 async textContent() {186 return throwRetargetableDOMError(await this.evaluateInUtility(([injected, node]) => {187 return {188 value: node.textContent189 };190 }, undefined)).value;191 }192 async innerText() {193 return throwRetargetableDOMError(await this.evaluateInUtility(([injected, node]) => {194 if (node.nodeType !== Node.ELEMENT_NODE) throw injected.createStacklessError('Node is not an element');195 if (node.namespaceURI !== 'http://www.w3.org/1999/xhtml') throw injected.createStacklessError('Node is not an HTMLElement');196 const element = node;197 return {198 value: element.innerText199 };200 }, undefined)).value;201 }202 async innerHTML() {203 return throwRetargetableDOMError(await this.evaluateInUtility(([injected, node]) => {204 if (node.nodeType !== Node.ELEMENT_NODE) throw injected.createStacklessError('Node is not an element');205 const element = node;206 return {207 value: element.innerHTML208 };209 }, undefined)).value;210 }211 async dispatchEvent(type, eventInit = {}) {212 await this._evaluateInMainAndWaitForSignals(([injected, node, {213 type,214 eventInit215 }]) => injected.dispatchEvent(node, type, eventInit), {216 type,217 eventInit218 });219 await this._page._doSlowMo();220 }221 async _scrollRectIntoViewIfNeeded(rect) {222 return await this._page._delegate.scrollRectIntoViewIfNeeded(this, rect);223 }224 async _waitAndScrollIntoViewIfNeeded(progress) {225 while (progress.isRunning()) {226 assertDone(throwRetargetableDOMError(await this._waitForDisplayedAtStablePosition(progress, false227 /* force */228 , false229 /* waitForEnabled */230 )));231 progress.throwIfAborted(); // Avoid action that has side-effects.232 const result = throwRetargetableDOMError(await this._scrollRectIntoViewIfNeeded());233 if (result === 'error:notvisible') continue;234 assertDone(result);235 return;236 }237 }238 async scrollIntoViewIfNeeded(metadata, options = {}) {239 const controller = new _progress.ProgressController(metadata, this);240 return controller.run(progress => this._waitAndScrollIntoViewIfNeeded(progress), this._page._timeoutSettings.timeout(options));241 }242 async _clickablePoint() {243 const intersectQuadWithViewport = quad => {244 return quad.map(point => ({245 x: Math.min(Math.max(point.x, 0), metrics.width),246 y: Math.min(Math.max(point.y, 0), metrics.height)247 }));248 };249 const computeQuadArea = quad => {250 // Compute sum of all directed areas of adjacent triangles251 // https://en.wikipedia.org/wiki/Polygon#Simple_polygons252 let area = 0;253 for (let i = 0; i < quad.length; ++i) {254 const p1 = quad[i];255 const p2 = quad[(i + 1) % quad.length];256 area += (p1.x * p2.y - p2.x * p1.y) / 2;257 }258 return Math.abs(area);259 };260 const [quads, metrics] = await Promise.all([this._page._delegate.getContentQuads(this), this._page.mainFrame()._utilityContext().then(utility => utility.evaluate(() => ({261 width: innerWidth,262 height: innerHeight263 })))]);264 if (!quads || !quads.length) return 'error:notvisible'; // Allow 1x1 elements. Compensate for rounding errors by comparing with 0.99 instead.265 const filtered = quads.map(quad => intersectQuadWithViewport(quad)).filter(quad => computeQuadArea(quad) > 0.99);266 if (!filtered.length) return 'error:notinviewport'; // Return the middle point of the first quad.267 const result = {268 x: 0,269 y: 0270 };271 for (const point of filtered[0]) {272 result.x += point.x / 4;273 result.y += point.y / 4;274 }275 compensateHalfIntegerRoundingError(result);276 return result;277 }278 async _offsetPoint(offset) {279 const [box, border] = await Promise.all([this.boundingBox(), this.evaluateInUtility(([injected, node]) => injected.getElementBorderWidth(node), {}).catch(e => {})]);280 if (!box || !border) return 'error:notvisible';281 if (border === 'error:notconnected') return border; // Make point relative to the padding box to align with offsetX/offsetY.282 return {283 x: box.x + border.left + offset.x,284 y: box.y + border.top + offset.y285 };286 }287 async _retryPointerAction(progress, actionName, waitForEnabled, action, options) {288 let retry = 0; // We progressively wait longer between retries, up to 500ms.289 const waitTime = [0, 20, 100, 100, 500]; // By default, we scroll with protocol method to reveal the action point.290 // However, that might not work to scroll from under position:sticky elements291 // that overlay the target element. To fight this, we cycle through different292 // scroll alignments. This works in most scenarios.293 const scrollOptions = [undefined, {294 block: 'end',295 inline: 'end'296 }, {297 block: 'center',298 inline: 'center'299 }, {300 block: 'start',301 inline: 'start'302 }];303 while (progress.isRunning()) {304 if (retry) {305 progress.log(`retrying ${actionName} action${options.trial ? ' (trial run)' : ''}, attempt #${retry}`);306 const timeout = waitTime[Math.min(retry - 1, waitTime.length - 1)];307 if (timeout) {308 progress.log(` waiting ${timeout}ms`);309 const result = await this.evaluateInUtility(([injected, node, timeout]) => new Promise(f => setTimeout(f, timeout)), timeout);310 if (result === 'error:notconnected') return result;311 }312 } else {313 progress.log(`attempting ${actionName} action${options.trial ? ' (trial run)' : ''}`);314 }315 const forceScrollOptions = scrollOptions[retry % scrollOptions.length];316 const result = await this._performPointerAction(progress, actionName, waitForEnabled, action, forceScrollOptions, options);317 ++retry;318 if (result === 'error:notvisible') {319 if (options.force) throw new Error('Element is not visible');320 progress.log(' element is not visible');321 continue;322 }323 if (result === 'error:notinviewport') {324 if (options.force) throw new Error('Element is outside of the viewport');325 progress.log(' element is outside of the viewport');326 continue;327 }328 if (typeof result === 'object' && 'hitTargetDescription' in result) {329 if (options.force) throw new Error(`Element does not receive pointer events, ${result.hitTargetDescription} intercepts them`);330 progress.log(` ${result.hitTargetDescription} intercepts pointer events`);331 continue;332 }333 return result;334 }335 return 'done';336 }337 async _performPointerAction(progress, actionName, waitForEnabled, action, forceScrollOptions, options) {338 const {339 force = false,340 position341 } = options;342 if (options.__testHookBeforeStable) await options.__testHookBeforeStable();343 const result = await this._waitForDisplayedAtStablePosition(progress, force, waitForEnabled);344 if (result !== 'done') return result;345 if (options.__testHookAfterStable) await options.__testHookAfterStable();346 progress.log(' scrolling into view if needed');347 progress.throwIfAborted(); // Avoid action that has side-effects.348 if (forceScrollOptions) {349 const scrolled = await this.evaluateInUtility(([injected, node, options]) => {350 if (node.nodeType === 1351 /* Node.ELEMENT_NODE */352 ) node.scrollIntoView(options);353 }, forceScrollOptions);354 if (scrolled === 'error:notconnected') return scrolled;355 } else {356 const scrolled = await this._scrollRectIntoViewIfNeeded(position ? {357 x: position.x,358 y: position.y,359 width: 0,360 height: 0361 } : undefined);362 if (scrolled !== 'done') return scrolled;363 }364 progress.log(' done scrolling');365 const maybePoint = position ? await this._offsetPoint(position) : await this._clickablePoint();366 if (typeof maybePoint === 'string') return maybePoint;367 const point = roundPoint(maybePoint);368 if (!force) {369 if (options.__testHookBeforeHitTarget) await options.__testHookBeforeHitTarget();370 progress.log(` checking that element receives pointer events at (${point.x},${point.y})`);371 const hitTargetResult = await this._checkHitTargetAt(point);372 if (hitTargetResult !== 'done') return hitTargetResult;373 progress.log(` element does receive pointer events`);374 }375 progress.metadata.point = point;376 if (options.trial) {377 progress.log(` trial ${actionName} has finished`);378 return 'done';379 }380 await progress.beforeInputAction(this);381 await this._page._frameManager.waitForSignalsCreatedBy(progress, options.noWaitAfter, async () => {382 if (options.__testHookBeforePointerAction) await options.__testHookBeforePointerAction();383 progress.throwIfAborted(); // Avoid action that has side-effects.384 let restoreModifiers;385 if (options && options.modifiers) restoreModifiers = await this._page.keyboard._ensureModifiers(options.modifiers);386 progress.log(` performing ${actionName} action`);387 await action(point);388 progress.log(` ${actionName} action done`);389 progress.log(' waiting for scheduled navigations to finish');390 if (options.__testHookAfterPointerAction) await options.__testHookAfterPointerAction();391 if (restoreModifiers) await this._page.keyboard._ensureModifiers(restoreModifiers);392 }, 'input');393 progress.log(' navigations have finished');394 return 'done';395 }396 async hover(metadata, options) {397 const controller = new _progress.ProgressController(metadata, this);398 return controller.run(async progress => {399 const result = await this._hover(progress, options);400 return assertDone(throwRetargetableDOMError(result));401 }, this._page._timeoutSettings.timeout(options));402 }403 _hover(progress, options) {404 return this._retryPointerAction(progress, 'hover', false405 /* waitForEnabled */406 , point => this._page.mouse.move(point.x, point.y), options);407 }408 async click(metadata, options = {}) {409 const controller = new _progress.ProgressController(metadata, this);410 return controller.run(async progress => {411 const result = await this._click(progress, options);412 return assertDone(throwRetargetableDOMError(result));413 }, this._page._timeoutSettings.timeout(options));414 }415 _click(progress, options) {416 return this._retryPointerAction(progress, 'click', true417 /* waitForEnabled */418 , point => this._page.mouse.click(point.x, point.y, options), options);419 }420 async dblclick(metadata, options) {421 const controller = new _progress.ProgressController(metadata, this);422 return controller.run(async progress => {423 const result = await this._dblclick(progress, options);424 return assertDone(throwRetargetableDOMError(result));425 }, this._page._timeoutSettings.timeout(options));426 }427 _dblclick(progress, options) {428 return this._retryPointerAction(progress, 'dblclick', true429 /* waitForEnabled */430 , point => this._page.mouse.dblclick(point.x, point.y, options), options);431 }432 async tap(metadata, options = {}) {433 const controller = new _progress.ProgressController(metadata, this);434 return controller.run(async progress => {435 const result = await this._tap(progress, options);436 return assertDone(throwRetargetableDOMError(result));437 }, this._page._timeoutSettings.timeout(options));438 }439 _tap(progress, options) {440 return this._retryPointerAction(progress, 'tap', true441 /* waitForEnabled */442 , point => this._page.touchscreen.tap(point.x, point.y), options);443 }444 async selectOption(metadata, elements, values, options) {445 const controller = new _progress.ProgressController(metadata, this);446 return controller.run(async progress => {447 const result = await this._selectOption(progress, elements, values, options);448 return throwRetargetableDOMError(result);449 }, this._page._timeoutSettings.timeout(options));450 }451 async _selectOption(progress, elements, values, options) {452 const optionsToSelect = [...elements, ...values];453 await progress.beforeInputAction(this);454 return this._page._frameManager.waitForSignalsCreatedBy(progress, options.noWaitAfter, async () => {455 progress.throwIfAborted(); // Avoid action that has side-effects.456 progress.log(' selecting specified option(s)');457 const poll = await this.evaluateHandleInUtility(([injected, node, {458 optionsToSelect,459 force460 }]) => {461 return injected.waitForElementStatesAndPerformAction(node, ['visible', 'enabled'], force, injected.selectOptions.bind(injected, optionsToSelect));462 }, {463 optionsToSelect,464 force: options.force465 });466 if (poll === 'error:notconnected') return poll;467 const pollHandler = new InjectedScriptPollHandler(progress, poll);468 const result = await pollHandler.finishMaybeNotConnected();469 await this._page._doSlowMo();470 return result;471 });472 }473 async fill(metadata, value, options = {}) {474 const controller = new _progress.ProgressController(metadata, this);475 return controller.run(async progress => {476 const result = await this._fill(progress, value, options);477 assertDone(throwRetargetableDOMError(result));478 }, this._page._timeoutSettings.timeout(options));479 }480 async _fill(progress, value, options) {481 progress.log(`elementHandle.fill("${value}")`);482 await progress.beforeInputAction(this);483 return this._page._frameManager.waitForSignalsCreatedBy(progress, options.noWaitAfter, async () => {484 progress.log(' waiting for element to be visible, enabled and editable');485 const poll = await this.evaluateHandleInUtility(([injected, node, {486 value,487 force488 }]) => {489 return injected.waitForElementStatesAndPerformAction(node, ['visible', 'enabled', 'editable'], force, injected.fill.bind(injected, value));490 }, {491 value,492 force: options.force493 });494 if (poll === 'error:notconnected') return poll;495 const pollHandler = new InjectedScriptPollHandler(progress, poll);496 const filled = await pollHandler.finishMaybeNotConnected();497 progress.throwIfAborted(); // Avoid action that has side-effects.498 if (filled === 'error:notconnected') return filled;499 progress.log(' element is visible, enabled and editable');500 if (filled === 'needsinput') {501 progress.throwIfAborted(); // Avoid action that has side-effects.502 if (value) await this._page.keyboard.insertText(value);else await this._page.keyboard.press('Delete');503 } else {504 assertDone(filled);505 }506 return 'done';507 }, 'input');508 }509 async selectText(metadata, options = {}) {510 const controller = new _progress.ProgressController(metadata, this);511 return controller.run(async progress => {512 progress.throwIfAborted(); // Avoid action that has side-effects.513 const poll = await this.evaluateHandleInUtility(([injected, node, force]) => {514 return injected.waitForElementStatesAndPerformAction(node, ['visible'], force, injected.selectText.bind(injected));515 }, options.force);516 const pollHandler = new InjectedScriptPollHandler(progress, throwRetargetableDOMError(poll));517 const result = await pollHandler.finishMaybeNotConnected();518 assertDone(throwRetargetableDOMError(result));519 }, this._page._timeoutSettings.timeout(options));520 }521 async setInputFiles(metadata, files, options) {522 const controller = new _progress.ProgressController(metadata, this);523 return controller.run(async progress => {524 const result = await this._setInputFiles(progress, files, options);525 return assertDone(throwRetargetableDOMError(result));526 }, this._page._timeoutSettings.timeout(options));527 }528 async _setInputFiles(progress, files, options) {529 for (const payload of files) {530 if (!payload.mimeType) payload.mimeType = mime.getType(payload.name) || 'application/octet-stream';531 }532 const retargeted = await this.evaluateHandleInUtility(([injected, node, multiple]) => {533 const element = injected.retarget(node, 'follow-label');534 if (!element) return 'error:notconnected';535 if (element.tagName !== 'INPUT') throw injected.createStacklessError('Node is not an HTMLInputElement');536 if (multiple && !element.multiple) throw injected.createStacklessError('Non-multiple file input can only accept single file');537 return element;538 }, files.length > 1);539 if (retargeted === 'error:notconnected') return retargeted;540 if (!retargeted._objectId) return retargeted.rawValue();541 await progress.beforeInputAction(this);542 await this._page._frameManager.waitForSignalsCreatedBy(progress, options.noWaitAfter, async () => {543 progress.throwIfAborted(); // Avoid action that has side-effects.544 await this._page._delegate.setInputFiles(retargeted, files);545 });546 await this._page._doSlowMo();547 return 'done';548 }549 async focus(metadata) {550 const controller = new _progress.ProgressController(metadata, this);...
Using AI Code Generation
1const { createStacklessError } = require('playwright/lib/utils/stackTrace');2const stacklessError = createStacklessError('Error message');3console.log(stacklessError.stack);4 at Object.<anonymous> (C:\Users\user\test.js:5:30)5 at Module._compile (internal/modules/cjs/loader.js:1137:30)6 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)7 at Module.load (internal/modules/cjs/loader.js:985:32)8 at Function.Module._load (internal/modules/cjs/loader.js:878:14)9 at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
Using AI Code Generation
1const { InternalError } = require('playwright/lib/utils/stackTrace');2const error = new InternalError('Test error');3console.log(error.stack);4 at Object.<anonymous> (/Users/username/playwright/test.js:3:13)5 at Module._compile (internal/modules/cjs/loader.js:1063:30)6 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)7 at Module.load (internal/modules/cjs/loader.js:928:32)8 at Function.Module._load (internal/modules/cjs/loader.js:769:14)9 at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)10 at Object.<anonymous> (/Users/username/playwright/test.js:3:13)11 at Module._compile (internal/modules/cjs/loader.js:1063:30)12 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)13 at Module.load (internal/modules/cjs/loader.js:928:32)14 at Function.Module._load (internal/modules/cjs/loader.js:769:14)15 at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)16 at Object.<anonymous> (/Users/username/playwright/test.js:3:13)17 at Module._compile (internal/modules/cjs/loader.js:1063:30)18 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)19 at Module.load (internal/modules/cjs/loader.js:928:32)20 at Function.Module._load (internal/modules/cjs/loader.js:769:14)21 at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)22 at Object.<anonymous> (/Users/username/playwright/test.js:3:13)23 at Module._compile (internal/modules/cjs/loader.js:1063:30)24 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10
Using AI Code Generation
1const { createStacklessError } = require('playwright/lib/utils/stackTrace');2const error = createStacklessError('My Error');3console.log(error);4const { createStacklessError } = require('playwright-test/lib/utils/stackTrace');5const error = createStacklessError('My Error');6console.log(error);7 at Object.<anonymous> (test.js:5:19)8 at Module._compile (internal/modules/cjs/loader.js:1063:30)9 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)10 at Module.load (internal/modules/cjs/loader.js:928:32)11 at Function.Module._load (internal/modules/cjs/loader.js:769:14)12 at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
Using AI Code Generation
1const {createStacklessError} = require("playwright/lib/utils/stackTrace");2const error = createStacklessError(new Error("Test error"), "Test error");3console.log(error);4console.log(error.stack);5 at Object.<anonymous> (C:\Users\test\test.js:7:27)6 at Module._compile (internal/modules/cjs/loader.js:1063:30)7 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)8 at Module.load (internal/modules/cjs/loader.js:928:32)9 at Function.Module._load (internal/modules/cjs/loader.js:769:14)10 at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)11 at Object.<anonymous> (C:\Users\test\test.js:7:27)12 at Object.<anonymous> (C:\Users\test\test.js:7:27)13 at Module._compile (internal/modules/cjs/loader.js:1063:30)14 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)15 at Module.load (internal/modules/cjs/loader.js:928:32)16 at Function.Module._load (internal/modules/cjs/loader.js:769:14)17 at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
Using AI Code Generation
1const { createStacklessError } = require('playwright-core/lib/utils/stackTrace');2const err = createStacklessError('Custom Error');3console.log(err);4const { createStacklessError } = require('playwright-core/lib/utils/stackTrace');5const { test, expect } = require('@playwright/test');6test('Test', async ({ page }) => {7 const err = createStacklessError('Custom Error');8 expect(err).toBeTruthy();9});
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!