I have creates a react app using react CLI.
I have now created a folder called data now I want to read that data using the xlsx npm package. However, it is not working. I think it may have something to do with the way I may be referring to the excel file because I get a warning as "Property 'Sheets' does not exist on type 'string'" (Pic below)
I thought it would be easy to read an excel (that too a local one), but I am not able to figure it out. Can anyone help? I looked at a lot of SO questions related to this but no success.
My Code
import "./App.css";
import XLSX from "xlsx";
let fileName = "./data/menu.xlsx";
var first_worksheet = fileName.Sheets[fileName.SheetNames[0]];
var data = XLSX.utils.sheet_to_json(first_worksheet, { header: 1 });
console.log(fileName);
Your fileName is just a string with your path right now. You're not actually parsing it as an Excel sheet yet, so the property Sheets will not exist on it.
You need to actually read the file from the filesystem, and then use XLSX to parse it into a format you can use to programmatically interact with it. Since you're using react, you can look at the react examples in the XLSX repo for an idea of how to go about it. The included demos only cover react-native apps, however, so you may also want to start looking into ways to retrieve and parse files on the local filesystem from the browser, like FileReader and fetch. Then, once you have the file loaded into memory, you can call XLSX.read(file) to fully interpret it as an Excel worksheet.
I found the answer to my question in here Excel to JSON javascript code?
The answer that was useful for me was the answer from user7456320 (the code is copied below as well).
All that was needed was the XLSX library. I used the code below with useEffect hook in my react component to run once when the page loads.
<!doctype html>
<html>
<head>
<title>Excel to JSON Demo</title>
<script src="xlsx.full.min.js"></script>
</head>
<body>
<script>
/* set up XMLHttpRequest */
var url = "http://myclassbook.org/wp-content/uploads/2017/12/Test.xlsx";
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";
oReq.onload = function(e) {
var arraybuffer = oReq.response;
/* convert data to binary string */
var data = new Uint8Array(arraybuffer);
var arr = new Array();
for (var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
var bstr = arr.join("");
/* Call XLSX */
var workbook = XLSX.read(bstr, {
type: "binary"
});
/* DO SOMETHING WITH workbook HERE */
var first_sheet_name = workbook.SheetNames[0];
/* Get worksheet */
var worksheet = workbook.Sheets[first_sheet_name];
console.log(XLSX.utils.sheet_to_json(worksheet, {
raw: true
}));
}
oReq.send();
</script>
</body>
</html>
I have baked new project. My simple ajax function inserted to ..\templates\Pages\home.php:
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "myTest.txt", true);
xhttp.send();
}
My myTest.txt is in ..\webroot\ location.
Why this works for homepage, but not for any other created site in project? For all sites except homepage cakePHP can not find my text file. I have tried various locations for this file.
You should use "/myTest.txt" for the URL to open. Without the / on the front, it is interpreted as a relative URL, so if you're at something like /page/2, then it will look for /page/myTest.txt, which doesn't exist.
Take HTTP_ROOT as constant in bootstrap.php holding the base url(site name without sub path).
define the <base href="<?= HTTP_ROOT;?>" /> on the layout->head section. this will help to hit the site without sub-path on ajax request.
you can take a further constant eg-"siteURL" in javascript inline code on the layout's <head> OR a hidden input holding the base path.
Use the constant if you need.
siteURL+(if any further dir under webroot)+'myTest.txt'
I am logging into a webPage using Selenium WebDriver in Jmeter, and want to check that all the links are working fine. For that, i wanted to check the response code returned when clicked on the link.
var links = WDS.browser.findElements(pkg.By.cssSelector("a"));
var href;
links.forEach(myFunction);
function myFunction(item) {
WDS.log.info("link value" + item);
href = item.getAttribute("href");
statusCode = new HttpResponseCode().httpResponseCodeViaGet(href);
if(200 != statusCode) {
System.out.println(href + " gave a response code of " + statusCode);
}
}
But the above code doesn't seem to be working. I would be glad if anyone could help me with this.
Also, is there any alternate way to check if all the links are working fine, in Jmeter Selenium Webdriver using javascript?
we're not able to help you unless you show us the code of the HttpResponseCode().httpResponseCodeViaGet beast and the relevant error message from the jmeter.log file.
If the above function is something you copied and pasted from StackOverflow, I strongly doubt that it will ever work because the language of the WebDriver Sampler is not that JavaScript which is being executed by your browser, it's a limited subset of the browser version of JavaScript (for example there is no XMLHttpRequest there)
Instead you have full access to underlying Java SDK and JMeter API so I would recommend amending your function as follows:
var links = WDS.browser.findElements(org.openqa.selenium.By.cssSelector("a"));
var href;
links.forEach(myFunction);
function myFunction(item) {
WDS.log.info("link value" + item);
href = item.getAttribute("href");
var client = org.apache.http.impl.client.HttpClientBuilder.create().build()
var request = new org.apache.http.client.methods.HttpGet(href)
var response = client.execute(request)
var statusCode = response.getStatusLine().getStatusCode()
if(200 != statusCode) {
WDS.log.error(href + " gave a response code of " + statusCode);
}
}
More information:
The WebDriver Sampler: Your Top 10 Questions Answered
HttpClient Tutorial
I want to test file uploading using an angularjs e2e test. How do you do this in e2e tests? I run my test script through grunt karma.
This is how I do it:
var path = require('path');
it('should upload a file', function() {
var fileToUpload = '../some/path/foo.txt',
absolutePath = path.resolve(__dirname, fileToUpload);
element(by.css('input[type="file"]')).sendKeys(absolutePath);
element(by.id('uploadButton')).click();
});
Use the path module to resolve the full path of the file that you want to upload.
Set the path to the input type="file" element.
Click on the upload button.
This will not work on firefox. Protractor will complain because the element is not visible. To upload in firefox you need to make the input visible. This is what I do:
browser.executeAsyncScript(function(callback) {
// You can use any other selector
document.querySelectorAll('#input-file-element')[0]
.style.display = 'inline';
callback();
});
// Now you can upload.
$('input[type="file"]').sendKeys(absolutePath);
$('#uploadButton').click();
You can't directly.
For security reason, you can not simulate a user that is choosing a file on the system within a functional testing suite like ngScenario.
With Protractor, since it is based on WebDriver, it should be possible to use this trick
Q: Does WebDriver support file uploads? A: Yes.
You can't interact with the native OS file browser dialog directly,
but we do some magic so that if you call
WebElement#sendKeys("/path/to/file") on a file upload element, it does
the right thing. Make sure you don't WebElement#click() the file
upload element, or the browser will probably hang.
This works just fine:
$('input[type="file"]').sendKeys("/file/path")
Here is a combo of Andres D and davidb583's advice that would have helped me as I worked through this...
I was trying to get protractor tests executed against the flowjs controls.
// requires an absolute path
var fileToUpload = './testPackages/' + packageName + '/' + fileName;
var absolutePath = path.resolve(__dirname, fileToUpload);
// Find the file input element
var fileElem = element(by.css('input[type="file"]'));
// Need to unhide flowjs's secret file uploader
browser.executeScript(
"arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1",
fileElem.getWebElement());
// Sending the keystrokes will ultimately submit the request. No need to simulate the click
fileElem.sendKeys(absolutePath);
// Not sure how to wait for the upload and response to return first
// I need this since I have a test that looks at the results after upload
// ... there is probably a better way to do this, but I punted
browser.sleep(1000);
var imagePath = 'http://placehold.it/120x120&text=image1';
element(by.id('fileUpload')).sendKeys(imagePath);
This is working for me.
This is what I do to upload file on firefox, this script make the element visible to set the path value:
browser.executeScript("$('input[type=\"file\"]').parent().css('visibility', 'visible').css('height', 1).css('width', 1).css('overflow', 'visible')");
If above solutions don't work, read this
First of all, in order to upload the file there should be an input element that takes the path to the file. Normally, it's immediately next to the 'Upload' button... BUT I've seen this, when the button doesn't have an input around the button which may seem to be confusing. Keep clam, the input has to be on the page! Try look for input element in the DOM, that has something like 'upload', or 'file', just keep in mind it can be anywhere.
When you located it, get it's selector, and type in a path to a file. Remember, it has to be absolute path, that starts from you root directory (/something/like/this for MAC users and C:/some/file in Windows)
await $('input[type="file"]').sendKeys("/file/path")
this may not work, if...
protractor's sendKeys can only type in an input that's visible. Often, the input will be hidden or have 0 pixels size. You can fix that too
let $input = $('input[type="file"]');
await browser.executeScript(
"arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1",
$input.getWebElement()
);
I realized that the file input in the web app I'm testing is only visible in Firefox when it is scrolled into view using JavaScript, so I added scrollIntoView() in Andres D's code to make it work for my app:
browser.executeAsyncScript(function (callback) {
document.querySelectorAll('input')[2]
.style = '';
document.querySelectorAll('input')[2].scrollIntoView();
callback();
});
(I also removed all of the styles for the file input element)
// To upload a file from C:\ Directory
{
var path = require('path');
var dirname = 'C:/';
var fileToUpload = '../filename.txt';
var absolutePath = path.resolve('C:\filename.txt');
var fileElem = ptor.element.all(protractor.By.css('input[type="file"]'));
fileElem.sendKeys(absolutePath);
cb();
};
If you want to select a file without opening the popup below is the answer :
var path = require('path');
var remote = require('../../node_modules/selenium-webdriver/remote');
browser.setFileDetector(new remote.FileDetector());
var fileToUpload = './resume.docx';
var absolutePath = path.resolve(process.cwd() + fileToUpload);
element(by.css('input[type="file"]')).sendKeys(absolutePath);
the current documented solutions would work only if users are loading jQuery. i all different situations users will get an error such:Failed: $ is not defined
i would suggest to document a solution using native angularjs code.
e.g. i would suggest instead of suggesting:
$('input[type="file"]') .....
to suggest:
angular.element(document.querySelector('input[type="file"]')) .....
the latter is more standard, atop of angular and more important not require jquery
I'm currently working on a Safari Extension that adds a stylesheet and some small scripts to a site. One of those scripts has to be inserted in the html, so I've another scripts running...
var myScriptElement = document.createElement('script');
myScriptElement.type = 'text/javascript';
myScriptElement.src = 'http://mysite.com/myscript.js';
document.querySelector('head').appendChild(myScriptElement);
...that adds this to the head:
<script type="text/javascript" src="http://mysite.com/myscript.js"></script>
The problem I have is that the scripts gets loaded from my site instead of the extension folder. So what do I have to insert as source to access the extension folder?
I can't insert the script using the standard start- and end-script-extension-function.
I'm really bad in javascripting so I would appreciate if someone of you could help me! :)
You can use safari.extension.baseURI to get the path to your extension folder. So use something like this in your injected script:
var myScriptElement = document.createElement('script');
myScriptElement.type = 'text/javascript';
myScriptElement.src = safari.extension.baseURI+'myscript.js';
document.querySelector('head').appendChild(myScriptElement);
It's worth noting that the injected script is injected into every iframe on the page too, so depending on what you are doing, you might want to ensure the above is only run if (window == window.top).