File's instanceof File is false. Two windows have different File classes.
See original GitHub issue- Operating System: Windows 7
- Cypress Version: 1.0.3
- Browser Version: Chrome 62
Is this a Feature or Bug?
Bug
Current behavior:
File class is not shared with window’s children.
Desired behavior:
File class is somehow shared.
How to reproduce:
- Write test and create a file in it.
- Use created file in app code (
instanceof File
)
Test code:
describe('Create new File', function() {
it('should has same File class', function() {
const file = new File(/* arguments */);
console.log(file instanceof File); // true
// test runs in new window with different File
doSomethingWithFile(file); // false
});
});
// App code
const doSomethingWithFile = file => console.log(file instanceof File);
Additional Info (images, stack traces, etc)
Where did I encounter a problem: https://github.com/jaydenseric/extract-files/blob/10236ac78548a3f9c64d148aa79e1444e8dff285/src/index.js#L33
Object.prototype.toString.call(node[key]) === "[object File]" // works
Temporary hack
// vendor/extract-files/index.js
// https://github.com/jaydenseric/extract-files/blob/master/src/index.js
// https://github.com/cypress-io/cypress/issues/933
/**
* Checks a node is an enumerable object.
* @param {*} node - A node to check.
* @returns {Boolean} Is the node an enumerable object.
*/
export const isObject = node => typeof node === 'object' && node !== null
/**
* A file extraction.
* @typedef {Object} ExtractedFile
* @property {String} path - Original location in the object tree.
* @property {String} file - The actual file.
*/
/**
* Reversibly extracts files from an object tree.
* @param {object} tree - An object tree to extract files from.
* @param {string} [treePath=''] - Optional tree path to prefix file paths.
* @returns {ExtractedFile[]} Extracted files.
*/
export function extractFiles(tree, treePath = '') {
const files = []
const recurse = (node, nodePath) => {
// Iterate enumerable properties of the node
Object.keys(node).forEach(key => {
// Skip non-object
if (!isObject(node[key])) return
const path = `${nodePath}${key}`
if (
// Node is a File
(typeof File !== 'undefined' &&
Object.prototype.toString.call(node[key]) === '[object File]') ||
// Node is a ReactNativeFile
node[key] instanceof ReactNativeFile
) {
// Extract the file and it's object tree path
files.push({ path, file: node[key] })
// Delete the file. Array items must be deleted without reindexing to
// allow repopulation in a reverse operation.
delete node[key]
// No further checks or recursion
return
}
if (typeof FileList !== 'undefined' && node[key] instanceof FileList)
// Convert read-only FileList to an array for manipulation
node[key] = Array.from(node[key])
// Recurse into child node
recurse(node[key], `${path}.`)
})
}
if (isObject(tree))
// Recurse object tree
recurse(
tree,
// If a tree path was provided, append a dot
treePath === '' ? treePath : `${treePath}.`
)
return files
}
/**
* A React Native FormData file object.
* @see {@link https://github.com/facebook/react-native/blob/v0.45.1/Libraries/Network/FormData.js#L34}
* @typedef {Object} ReactNativeFileObject
* @property {String} uri - File system path.
* @property {String} [type] - File content type.
* @property {String} [name] - File name.
*/
/**
* A React Native file.
*/
export class ReactNativeFile {
/**
* Constructs a new file.
* @param {ReactNativeFileObject} file
* @example
* const file = new ReactNativeFile({
* uri: uriFromCameraRoll,
* type: 'image/jpeg',
* name: 'photo.jpg'
* })
*/
constructor({ uri, type, name }) {
this.uri = uri
this.type = type
this.name = name
}
/**
* Creates an array of file instances.
* @param {ReactNativeFileObject[]} files
* @example
* const files = ReactNativeFile.list([{
* uri: uriFromCameraRoll1,
* type: 'image/jpeg',
* name: 'photo-1.jpg'
* }, {
* uri: uriFromCameraRoll2,
* type: 'image/jpeg',
* name: 'photo-2.jpg'
* }])
*/
static list = files => files.map(file => new ReactNativeFile(file))
}
// package.json (this works only for yarn)
"resolutions": {
"apollo-upload-client/extract-files": "file:./vendor/extract-files"
}
// webpack.config.js
module: {
rules: [
{
test: /\.(js|jsx|mjs)$/,
include: [
path.resolve(__dirname, '../node_modules/extract-files'),
// ...
],
}
]
}
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (5 by maintainers)
Top Results From Across the Web
A File object in Chrome passed between windows is no longer ...
You're checking against the wrong File class. Since each window has its own scope, you need files[0] instanceof opener.File.
Read more >Chapter 4. The class File Format - Oracle Help Center
A class file consists of a stream of 8-bit bytes. All 16-bit, 32-bit, and 64-bit quantities are constructed by reading in two, four,...
Read more >Class.isInstance vs Class.isAssignableFrom and instanceof
In this quick tutorial, we're going to take a look at the difference between instanceof, Class.isInstance, and Class.isAssignableFrom.
Read more >Type Operators - Manual - PHP
instanceof is used to determine whether a PHP variable is an instantiated object of a certain class: Example #1 Using instanceof with classes....
Read more >jdk8/jdk8/jdk: 687fd7c7986d src/share/classes/java/io/File.java
The file * system may have multiple sets of access permissions on a single ... and classes for the Java virtual machine to...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
This should be fairly simple to fix: you simply need to instantiate Files from your application’s window, and not from the test spec window.
@tnrich I agree, this would be great. You can express your interest in this feature here: https://github.com/cypress-io/cypress/issues/170