UNPKG

@wordpress/e2e-test-utils-playwright

Version:
8 lines (7 loc) 7.55 kB
{ "version": 3, "sources": ["../../src/page-utils/drag-files.ts"], "sourcesContent": ["/**\n * External dependencies\n */\nimport { readFile } from 'fs/promises';\nimport { basename } from 'path';\nimport { getType } from 'mime';\n\n/**\n * Internal dependencies\n */\nimport type { PageUtils } from './index';\nimport type { Locator } from '@playwright/test';\n\ntype FileObject = {\n\tname: string;\n\tmimeType?: string;\n\tbuffer: Buffer;\n};\n\ntype Options = {\n\tposition?: { x: number; y: number };\n};\n\n/**\n * Simulate dragging files from outside the current page.\n *\n * @param this\n * @param files The files to be dragged.\n * @return The methods of the drag operation.\n */\nasync function dragFiles(\n\tthis: PageUtils,\n\tfiles: string | string[] | FileObject | FileObject[]\n) {\n\tconst filesList = Array.isArray( files ) ? files : [ files ];\n\tconst fileObjects = await Promise.all(\n\t\tfilesList.map( async ( filePathOrObject ) => {\n\t\t\tif ( typeof filePathOrObject !== 'string' ) {\n\t\t\t\treturn {\n\t\t\t\t\tname: filePathOrObject.name,\n\t\t\t\t\tmimeType:\n\t\t\t\t\t\tfilePathOrObject.mimeType ||\n\t\t\t\t\t\tgetType( filePathOrObject.name ),\n\t\t\t\t\tbase64: filePathOrObject.buffer.toString( 'base64' ),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst base64 = await readFile( filePathOrObject, 'base64' );\n\t\t\tconst name = basename( filePathOrObject );\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\tmimeType: getType( filePathOrObject ),\n\t\t\t\tbase64,\n\t\t\t};\n\t\t} )\n\t);\n\n\t// CDP doesn't actually support dragging files, this is only a _good enough_\n\t// dummy data so that it will correctly send the relevant events.\n\tconst dragData = {\n\t\titems: fileObjects.map( ( fileObject ) => ( {\n\t\t\tmimeType: fileObject.mimeType ?? 'File',\n\t\t\tdata: fileObject.base64,\n\t\t} ) ),\n\t\tfiles: fileObjects.map( ( fileObject ) => fileObject.name ),\n\t\t// Copy = 1, Link = 2, Move = 16.\n\t\tdragOperationsMask: 1,\n\t};\n\n\tconst cdpSession = await this.context.newCDPSession( this.page );\n\n\tconst position = {\n\t\tx: 0,\n\t\ty: 0,\n\t};\n\n\treturn {\n\t\t/**\n\t\t * Drag the files over an element (fires `dragenter` and `dragover` events).\n\t\t *\n\t\t * @param selectorOrLocator A selector or a locator to search for an element.\n\t\t * @param options The optional options.\n\t\t * @param options.position A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the element.\n\t\t */\n\t\tdragOver: async (\n\t\t\tselectorOrLocator: string | Locator,\n\t\t\toptions: Options = {}\n\t\t) => {\n\t\t\tconst locator =\n\t\t\t\ttypeof selectorOrLocator === 'string'\n\t\t\t\t\t? this.page.locator( selectorOrLocator )\n\t\t\t\t\t: selectorOrLocator;\n\t\t\tconst boundingBox = await locator.boundingBox();\n\n\t\t\tif ( ! boundingBox ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Cannot find the element or the element is not visible on the viewport.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tposition.x =\n\t\t\t\tboundingBox.x +\n\t\t\t\t( options.position?.x ?? boundingBox.width / 2 );\n\t\t\tposition.y =\n\t\t\t\tboundingBox.y +\n\t\t\t\t( options.position?.y ?? boundingBox.height / 2 );\n\n\t\t\tawait cdpSession.send( 'Input.dispatchDragEvent', {\n\t\t\t\ttype: 'dragEnter',\n\t\t\t\t...position,\n\t\t\t\tdata: dragData,\n\t\t\t} );\n\t\t\tawait cdpSession.send( 'Input.dispatchDragEvent', {\n\t\t\t\ttype: 'dragOver',\n\t\t\t\t...position,\n\t\t\t\tdata: dragData,\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Drop the files at the current position.\n\t\t */\n\t\tdrop: async () => {\n\t\t\tconst topMostElement = await this.page.evaluateHandle(\n\t\t\t\t( { x, y } ) => {\n\t\t\t\t\tconst element = document.elementFromPoint( x, y );\n\t\t\t\t\tif ( element instanceof HTMLIFrameElement ) {\n\t\t\t\t\t\tconst offsetBox = element.getBoundingClientRect();\n\t\t\t\t\t\treturn element.contentDocument!.elementFromPoint(\n\t\t\t\t\t\t\tx - offsetBox.x,\n\t\t\t\t\t\t\ty - offsetBox.y\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn element;\n\t\t\t\t},\n\t\t\t\tposition\n\t\t\t);\n\t\t\tconst elementHandle = topMostElement.asElement();\n\n\t\t\tif ( ! elementHandle ) {\n\t\t\t\tthrow new Error( 'Element not found.' );\n\t\t\t}\n\n\t\t\tconst dataTransfer = await elementHandle.evaluateHandle(\n\t\t\t\tasync ( _node, _fileObjects ) => {\n\t\t\t\t\tconst dt = new DataTransfer();\n\t\t\t\t\tconst fileInstances = await Promise.all(\n\t\t\t\t\t\t_fileObjects.map( async ( fileObject: any ) => {\n\t\t\t\t\t\t\tconst blob = await fetch(\n\t\t\t\t\t\t\t\t`data:${ fileObject.mimeType };base64,${ fileObject.base64 }`\n\t\t\t\t\t\t\t).then( ( res ) => res.blob() );\n\t\t\t\t\t\t\treturn new File( [ blob ], fileObject.name, {\n\t\t\t\t\t\t\t\ttype: fileObject.mimeType ?? undefined,\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t\tfileInstances.forEach( ( file ) => {\n\t\t\t\t\t\tdt.items.add( file );\n\t\t\t\t\t} );\n\n\t\t\t\t\treturn dt;\n\t\t\t\t},\n\t\t\t\tfileObjects\n\t\t\t);\n\n\t\t\tawait elementHandle.dispatchEvent( 'drop', { dataTransfer } );\n\n\t\t\tawait cdpSession.detach();\n\t\t},\n\t};\n}\n\nexport { dragFiles };\n"], "mappings": "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", "names": [] }