Cypress: How to test upload a folder with files and subfolders? - javascript

I'm having an issue to test uploading a folder with files and subfolders. If I add folder structure to the fixture then cy.fixture() command doesn't recognize that is a directory that I want to upload but it looks inside the directory to find the files. I have tries also to use the cy.readFile() but I couldn't make it to work.
I have tried to create drag and drop command like this:
Cypress.Commands.add('dragAndDropFolder', (fileUrl, type = '') => {
return cy.readFile(fileUrl, 'binary')
.then(Cypress.Blob.binaryStringToArrayBuffer)
.then(blob => {
const nameSegments = fileUrl.split('/');
const name = nameSegments[nameSegments.length - 1];
const testFile = new File([blob], name, { type });
const event = {
dataTransfer: {
isDirectory: true,
isFile: false,
fullPath: `#${fileUrl}`,
files: [testFile],
items: [{ kind: 'file', type }],
types: ['Files'],
},
};
return cy
.get('[data-test-dropzone="true"]')
.first()
.trigger('dragenter', event)
.trigger('drop', event);
});
});
Another thing I have tried to use a our different functionality which is simple upload button and the attachFile() plugin:
cy.readFile('client/testfolder', 'binary').then(file => {
cy.get('#multiple_file_uploads_input').attachFile(file)
});
Drag and drop functionality is written in Elixir and this is how data transfer looks like:
{
isDirectory: true,
isFile: false,
fullPath: '#{path}',
createReader() {
return {
sentEntries: false,
readEntries(callback) {
if (!this.sentEntries) {
this.sentEntries = true;
callback([#{Enum.join(entries, ",")}]);
} else {
callback([]);
}
},
};
},
}

At least on Elixir side the fullPath: '#{path}', will be substituted by the real path like fullPath: '/some/path', so you need to remove hash (#) from your path at JavaScript side here fullPath: '#${fileUrl}',, probably could be just fullPath: fileUrl,

Related

Adding file to dropzone Cypress

I am trying to add a pdf file to a dropzone in a Cypress test that Im creating
Ive added the cypress-upload-file package to help me do this.
In my commands.js file I have
Cypress.Commands.add("AddCandidate", function (candidate) {
cy.contains("Candidates").click()
cy.contains('Import Candidate').click()
cy.get('[id="resumeDz"]')
.attachFile({ './resumes': 'example.pdf', encoding: 'utf-8', subjectType: 'drag-n-drop' });})
and in my test I have
/// <reference types="cypress" />
describe('Add candidate', () => {
before(function () {
cy.visit(Cypress.env("home_page"));
cy.fixture('user').then(function (user) {
this.user = user
cy.SignIn({ email: (this.user.email), password: (this.user.password) })
})
})
it('Adds Candidate', function () {
cy.AddCandidate({})
})})
When running the test I get `"filePath" is not valid.
Please look into docs to find supported "filePath" values
Is there a specific way that i need to define the path ? Ive tried adding the full path, but Im still getting the same error. Is there something im missing ?`
SOLUTION
I ended up finding the solution.
Cypress.Commands.add("AddCandidate", function (candidate) {
cy.contains("Candidates").click()
cy.contains('Import Candidate').click()
cy.fixture('example.pdf', 'binary')
.then(Cypress.Blob.binaryStringToBlob)
.then(fileContent => {
cy.get('[type="file"]').attachFile({
fileContent,
filePath: 'example.pdf',
fileName: 'example.pdf',
});
cy.wait(1000)
cy.contains('Start').click()
cy.contains('Done').click()
});
})
The arguments to .attachFile() are a little messed up
cy.get('[id="resumeDz"]')
.attachFile('./resumes/example.pdf', {
encoding: 'utf-8',
subjectType: 'drag-n-drop'
});
presuming ./resumes/example.pdf is the path to the file relative to the fixtures folder.
With newer versions you can use the native cypress drag&drop action:
cy.get('#dropzone')
.selectFile('cypress/fixtures/file.txt', { action: 'drag-drop' });

MoleculerJs with Jaeger tracing: how to trace follow up action calls (new spans) in one trace

I would like to display all my traces like in the examples from the moleculer-jaeger package:
But what i get is something like this:
All spans you can see in this picture should be within the main trace (gateway).
Here is my moleculer.config:
tracing: {
enabled : true,
stackTrace: true,
actions : true,
exporter : {
type : 'Jaeger',
options: {
// HTTP Reporter endpoint. If set, HTTP Reporter will be used.
endpoint: 'http://jaeger:14268/api/traces',
// UDP Sender host option.
host : 'api.dev.host.com',
// UDP Sender port option.
port : 6832,
// Jaeger Sampler configuration.
sampler : {
// Sampler type. More info: https://www.jaegertracing.io/docs/1.14/sampling/#client-sampling-configuration
type : 'Const',
// Sampler specific options.
options: {
}
},
// Additional options for `Jaeger.Tracer`
tracerOptions: {},
// Default tags. They will be added into all span tags.
defaultTags : {
appName: 'core',
}
}
},
tags: {
action: {
// Always add the response
response: true,
},
},
},
My jaeger-service is just one of the examples:
const JaegerService = require('moleculer-jaeger')
module.exports = {
mixins : [ JaegerService ],
settings: {
host : 'jaeger-server',
port : 6832,
sampler: {
type : 'Const',
options: {
decision: 1
}
}
}
}
I tried several different configurations for sampling but nothing worked the way i would like it to have.
Here is some code where you can see the action calls i do:
// serviceX endpoint:
resolveByName: {
rest : 'GET resolve/name/:name',
params: {
name: { type: 'string' }
},
handler(ctx) {
return resolveByNameHandler(this.broker, ctx.params, 'serviceY')
}
},
// handler code
// please do not focus on the code itself. What i wanted to show is how i call the other
// services.
const { NotFoundError } = require(`${process.env.INIT_CWD}/util/error`)
module.exports = (broker, params, dataSource) => {
const { name } = params
const query = { name: name }
const rejectRequest = (name, data) => Promise.reject(new NotFoundError(name, data))
const getSourceData = result => broker.call(`${dataSource}.find`, { query: { id: result[0].ownerId } })
.then(sourceData => sourceData.length === 0
? rejectRequest(dataSource, sourceData)
: mergeResult(sourceData, result))
const mergeResult = (sourceData, result) => ({ ...sourceData[0], origin: { ...result[0], source: 'serviceX' } })
return broker.call('serviceX.find', { query: query })
.then(result => result.length === 0 ? rejectRequest('serviceX', query): result)
.then(result => result[0].ownerId ? getSourceData(result) : rejectRequest('noOwnerId', query))
}
What i also tried is to not use the moleculer-jaeger package but to use the jaeger all-in-one docker image. Same results though...
# from the docker-compose.yml
jaeger-server:
image: jaegertracing/all-in-one:latest
ports:
- 5775:5775/udp
- 6831:6831/udp
- 6832:6832/udp
- 5778:5778
- 16686:16686
- 14268:14268
- 9411:9411
networks:
- internal
What i do not want to do is to set the spans manually in every service. I have tried it already but it did not work at all, so if this would be the only solution i would be very happy to see an example.
Thanks in advance!
*edit:
The Versions i use:
{
"jaeger-client": "^3.18.1",
"moleculer": "^0.14.13",
"moleculer-db": "^0.8.12",
"moleculer-db-adapter-mongoose": "^0.8.9",
"moleculer-jaeger": "^0.2.3",
"moleculer-web": "^0.9.1",
"mongoose": "^5.12.5",
}
This version already has a built-in jager tracer, see the documentation.
In order for the events to be nested, it is necessary to transfer the context inside the actions, use ctx.call calls instead of broker.call, so they will be nested.
To quickly receive support for the moleculer, join us in discord!

Display full folder path in console using electron and Javascript

Im using electron with a python backend (for a stand alone desktop application) and I need to supply the python script with a directory. With the following code I can get a dialog to open however, it will not output the folder path to the console.
const OpenBtn = document.getElementById('OpenBtn')
OpenBtn.addEventListener('click', function(event) {
const { dialog } = require('electron').remote;
//Synchronous
let dir = dialog.showOpenDialog({properties:["openDirectory"]})
console.log(dir)
})
I am new to the frontend aspects of creating apps and I am trying to understand what is contained in dir. I see it produces a "promise" (I've tried various ways of accessing the filePaths string, but without success.
There is an HTML button with id=OpenBtn, and I have
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true
}
in my main.js file.
Either use the synchronous showOpenDialogSync:
let dirs = dialog.showOpenDialogSync({properties:["openDirectory"]})
if (typeof dirs !== "undefined") {
console.log("Selected paths:");
console.log(dirs);
}
Or the asynchronous showOpenDialog:
dialog.showOpenDialog({properties: ["openDirectory"]}).then(result => {
if (result.canceled === false) {
console.log("Selected paths:");
console.log(result.filePaths);
}
}).catch(err => {
console.log(err);
})

How to rename a file in uppy? javascript

I am trying to rename files in uppy.js. According to the documentation, there are 2 functions that are capable of providing this functionality. I defined both of these functions, however, they are having no effect on the file name and no errors are being thrown. How can I use these functions to rename a file?
onBeforeFileAdded: (currentFile, files) => {
const modifiedFile = {
...currentFile,
name: currentFile.name + '__' + Date.now()
}
return modifiedFile
}
onBeforeUpload: (files) => {
if (Object.keys(files).length < 2) {
// log to console
uppy.log(`Aborting upload because only ${Object.keys(files).length} files were selected`)
// show error message to the user
uppy.info(`You have to select at least 2 files`, 'error', 500)
return false
}
}
You need to make sure that the callback you posted is passed into your main uppy core initialization. It should work then as it is for me. Best of luck.
Hopefully, the code below can help you out.
const Uppy = require('#uppy/core');
let uppy = Uppy({
autoProceed: false,
allowMultipleUploads: true,
logger: Uppy.debugLogger,
restrictions: {
maxNumberOfFiles: 15,
maxFileSize: 10000000,
minNumberOfFiles: 1,
allowedFileTypes: ['image/*']
},
onBeforeFileAdded: (currentFile, files) => {
const modifiedFile = {
...currentFile,
name: 'yourfilename' + Date.now()
}
return modifiedFile
}
})

React download an image from uri and put in static folder? [duplicate]

I am building an app with React Native, for Android and iOS. I am trying to let the user download a PDF file when clicking on a button.
react-native-file-download does not support Android
react-native-fs does nothing when I trigger downloadFile (nothing shows up on the notification bar), and I am not able to find the file after that. I added android.permission.WRITE_EXTERNAL_STORAGE to the Android Manifest file. I double-checked that the file I am trying to download exists (when it does not, the library throws an error)
I do not find other solutions for this problem. I have found libraries for viewing a PDF, but I would like to let the user download the PDF.
Just implemented the download feature an hour ago :p
Follow these steps:
a) npm install rn-fetch-blob
b) follow the installation instructions.
b2) if you want to manually install the package without using rnpm, go to their wiki.
c) Finally, that's how I made it possible to download files within my app:
const { config, fs } = RNFetchBlob
let PictureDir = fs.dirs.PictureDir // this is the pictures directory. You can check the available directories in the wiki.
let options = {
fileCache: true,
addAndroidDownloads : {
useDownloadManager : true, // setting it to true will use the device's native download manager and will be shown in the notification bar.
notification : false,
path: PictureDir + "/me_"+Math.floor(date.getTime() + date.getSeconds() / 2), // this is the path where your downloaded file will live in
description : 'Downloading image.'
}
}
config(options).fetch('GET', "http://www.example.com/example.pdf").then((res) => {
// do some magic here
})
If you're using Expo, react-native-fetch-blob won't work. Use FileSystem.
Here's a working example:
const { uri: localUri } = await FileSystem.downloadAsync(remoteUri, FileSystem.documentDirectory + 'name.ext');
Now you have localUri with the path to the downloaded file. Feel free to set your own filename instead of name.ext.
I Followed the solution from Jonathan Simonney, above on this post. But I had to change it a little:
const { config, fs } = RNFetchBlob;
const date = new Date();
const { DownloadDir } = fs.dirs; // You can check the available directories in the wiki.
const options = {
fileCache: true,
addAndroidDownloads: {
useDownloadManager: true, // true will use native manager and be shown on notification bar.
notification: true,
path: `${DownloadDir}/me_${Math.floor(date.getTime() + date.getSeconds() / 2)}.pdf`,
description: 'Downloading.',
},
};
config(options).fetch('GET', 'http://www.africau.edu/images/default/sample.pdf').then((res) => {
console.log('do some magic in here');
});
GetItem_downloadbtn = (item, itemname) => {
console.log("fiel url comiugn jdd " + item);
console.log("item name checkoing " + itemname);
const android = RNFetchBlob.android;
const filename = itemname;
const filepath = RNFetchBlob.fs.dirs.DownloadDir + '/foldernamae/' + filename;
const downloadAppUrl = item;
RNFetchBlob.config({
addAndroidDownloads: {
useDownloadManager: true,
title: 'great, download success',
description:'an apk that will be download',
mime: 'application/vnd.android.package-archive',
// mime: 'image/jpeg',
// mediaScannable: true,
notification: true,
path: filepath
}
})
.fetch('GET', downloadAppUrl)
.then((res) => {
// console.log('res.path ', res.path());
alert('res.path ', res.path());
android.actionViewIntent(res.path(), 'application/vnd.android.package-archive');
})
.catch((err) => {
alert('download error, err is', JSON.stringify(err));
});
}
I had the same issue, got it working using Expo WebBrowser Module
// install module
npm install react-native-webview
// import the module
import * as WebBrowser from 'expo-web-browser';
// then in your function you can call this function
await WebBrowser.openBrowserAsync(file_ur);
it will open preview of the file and then user can download using share button.

Categories

Resources