Mixing Client-/Server-Side Tests - javascript

How should I structure tests containing a mixture of Selenium code (for setting up the page), and client-side Mocha code (for actually performing the tests on the client-side JS being tested)?
I am testing a client-side javascript library. Unit tests work great with Karma, Mocha, and Grunt. The unit-tests can be run locally, or via SauceLabs. The unit tests are able to test basically everything up to the part where a file is actually submitted. This part requires browser automation, and/or manual interaction, and this is what I'm struggling with.
The library in question is a Javascript file-upload library. It has features like chunking, auto-resuming, and much more. It does not require jQuery, and it works on a variety of browsers (IE7-10, FF, Safari (Mac & iOS), Chrome, Android stock browser). So, there are a lot of cases and exceptions to be covered in these tests.
Basically, I need to use Selenium to set up the page. Since I'm testing a client-side JS file-upload library I need to use Selenium to programmatically submit a file so it can actually be uploaded. Once this file has been submitted (the equivalent of selecting a file from the dialog window that appears when you try to upload a file or files online) then client-side tests can be run to ensure the UI has been drawn properly, the file has been found, etc.
I'm trying to wrap my head around how I can test this properly, and how I can set up my test suite to be extensible for the future, robust, and simple/easy to use.
Should I inject JS code to be run client-side with Selenium?
One idea is to inject the client-side JS code at opportune times with Selenium. Here's some pseudo-code of what I'm thinking:
describe("A Test", function () {
it("injects some JS", function (done) {
// Assume `getClientSideScript` loads some .js file from the filesystem,
// reads its contents, and returns the contents as a string (to be executed).
browser.safeExecute(getClientSideScript('initialize'), function (err, result) {
// At this point, the client-side library is initialized on the page.
// Assume that `uploadFile` will submit a file to the `<input type='file'>`
// element
utils.uploadFile('file.jpg', function (file) {
browser.safeExecute(getClientSideScript('test_file_submission'), function (err, result) {
assert.ok(/* something about the result */);
});
});
});
});
});
This, to me, would work, but seems like a giant PITA. I would have to come up with some convention for storing and loading the client-side scripts that are loaded. Also, two different test would have two different injected scripts so we'd have a huge collection of one-time-use scripts chillin' out in our repo. I'm also afraid of going down this road and finding out that it is a bad decision or impossible.
Anyone have any experience with this?
Mock server...I'm going to need one.
I could use Sinon.js to make mock servers client-side, or nock to have a separate server-side mock server. The server is super simple, but I believe I need to able to assert client-side that the response from the server was what was expected.
Intercepting client-side test results
Similar to the above, how would I be able to intercept asserts within the client-side code when using Selenium to automate the browser. For example, let's say I wanted to test a request-response cycle between my library and a mock server and I wanted to verify that if my library sends request A to the server it will expect response A. Selenium can't test that. I need to be able to have asserts captured client-side and outputted through Selenium.
Been bangin' my head on the wall trying to figure out the best method to do this. If anyone has any experience with anything similar, please, chime in!

I wouldn't mix these two types of tests at all. You have several different concerns here. You can still get full test coverage without having to combine tests like you are describing.
Client side unit tests (using Karma, Mocha, etc.) validate that the JavaScript code is behaving as expected.
Server side unit tests (using JUnit or whatever unit testing framework exists for your back end) validate that the server code is behaving as expected.
Integration or end-to-end tests (using Selenium) validate generally validate that multiple components are working together correctly. You can use a mock back-end for these if necessary.
You can create Karma/Mocha unit tests to verify the details of whatever processing may exist for that file upload action. Here, you should be testing edge cases of the individual JavaScript functions underneath the UI.
You can then create a Selenium test to purely test the upload action and expected result of uploading the file. You can verify that the correct elements exist on the page and have the expected properties after the upload. The JavaScript is a black box in this case. You are testing from the user's perspective. This will exercise some of the code you unit tested already, but the point of it is to test the connection between front and back ends.

Related

How do I create an automated API test in Microsoft Playwright?

Is it possible to create API automation tests in Microsoft Playwright? If so how do I create the following POST request as an automated test in Playwright using javascript?
Please note below is just an example.
POST
https://pokeapi.co/api/v2/pokemon-form/1/
BODY
{
"name":"test"
}
3rd party edit
The answer given below points to the playwright api testing documentation but the problem is, that the documentations is quite brief.
It is unclear to me
If i need to create a project first using npm init playwright#latest
Do i need to download the browsers again or can i cancel this steps because i already downloaded the browsers
In which file and folder do i need to put the codes sample provided?
For one code sample the file is playwright.config.js
But the first code sample Writing Tests makes no statement into which file it should be placed
The same is the case for setup and teardown: what are the file names and into which folder must they be placed?
The same is the case for the other chapters: using-request-context, sending-api-requests-from-ui-tests and so on
How can the sample be run / started / executed?
Yes you can run API tests with Playwright. It can be done in a standalone way without using the browser context at all, and also possible while using the browser context.
Playwright is quite different from Cypress in this case since cypress always considers all tests as browser tests, but with playwright requests feature, you can run API tests in standalone mode.
You can see all the required information here.
https://playwright.dev/docs/test-api-testing

Stress testing a JAvascript file which only runs in the browser

I need to run a Javascript file for a relatively long time(maybe about 5 weeks or so at one time), without it stopping or being interrupted. Currently the script is a client side script which connects to the server and receives data via Sockjs. There is no HTMl/GUI. There is only some computation.
I need to make sure the client always stays connected to the server all the time. I need to be able to run some script from the command line which is like forever.js. I have tried porting the javascript to node.js but it doesnt work. It only works in the browser. I have tried reading the file and doing an eval but none of it works. Are there any other options open for me? I have tried phantomJS but that doesnt work too. I have looked at How can I use a javascript library on the server side of a NodeJS app when it was designed to run on the client? and Load "Vanilla" Javascript Libraries into Node.js but I reapeatedly get SockJS is not defined. I guess the problem lies deep in the library and is not a simple fix.
Could anyone give me some pointers? What are my other options? Whats the best way to test a client javascript library which seems to work only on the browser?
This is the repo I am using :
https://github.com/sockjs/sockjs-client
It doesnt seems to be running on node. I tried to replace the script tag with require, and download the sock.js into a separate file and use it.
There are "headless" browser modules available. These produce a virtual browser environment that can be programatically controlled. The primary use of these is to do unit/integration testing of browser side code without actually running a browser:
Phantomjs
Slimerjs
These might fit your needs. You can create a nodejs script that will load the said code in a virtual browser page.

Are there any reporting library in Javascript/Angular.js?

I want to generate some reports in a MEAN.js Application, that said, i manage the data in Angular, what i want to know is if there's a library to generate a PDF Report, for example, when using PHP there's dompdf, fpdf, etc...
Basically what i need to generate is something like this from Angular:
Are there any tool to generate the reports from Angular, or should i generate them from Node.js? if so what are the tools available for node.js?
I only know about jsreport for node.js
Server-side rendering with Node is definitely the way to go, the client side libraries never really worked well (I last checked about a year ago). I'd suggest using PhantomJS as it provides PDF rendering capabilities out of the box.
PhantomJS will use Webkit engine to generate the PDF for you. The actual rendering process is dead simple:
page.render('/tmp/file.pdf', function() {
// file is now written to disk
});
Of course you have to insert something on the page you're generating first. Check out the following post which describes one guy's implementation, the code quoted above comes from there: http://www.feedhenry.com/server-side-pdf-generation-node-js/

running javascript plugins in node

I'm not sure if this is possible without some serious tweaking but is it possible to run javascript plugins server side with node...
more specifically
I would like to run the dymo javascript sdk from node (the printer is attached to the server)
that way any device can print from the server.
I have tried using https://github.com/tojocky/node-printer as a workaround however it doesnt work in my situation (works with my laserjet though)
I have tried just requiring the file that failed miserably.
if this is possible can you just point me in the right direction I have been searching the google and even been corresponding with dymo developers however I havent gotten much help from them.
so the simplest way to put it: Can you run clientside javascript plugins from server side? if not is there a way to write a middleware that will act as a bridge?
here is the plugin file(before I modify it more): http://irwinproject.com/jss/Dymo.js
its a bunch of craziness. I am trying to modify it to work as a module
UPDATE: I have gotten most of the functions running properly however I have hit a bit of a snag their sdk requires active x which I dont understand because I'm on a mac and it works
can someone explain to me how active x can function client side on a mac? (i thought that was windows only) and also is there anyway to implement the same framework(activex or other) through node
if I understand this correctly active x is used as an abstraction layer between javascript and hardware
You have to return your object or functions with module.exports, also try to verify you are requiring your file with . so node knows is a local module.
Check this SO post with a highly upvoted answer :
What is the purpose of Node.js module.exports and how do you use it?
module.exports is the object that's actually returned as the result of
a require call.
The exports variable is initially set to that same object (i.e. it's a
shorthand "alias"), so in the module code you would usually write
something like this....

Unit testing a modular Javascript web-app

I am building a web app using BackboneJS and RequireJS and need to implement some form of unit testing for UI interaction and data retrieval via AJAX. I have come across QUnit and Jasmine but don't really know how I can integrate this into my app.
If I am testing things such as:
Is the user logged in alright?
Has the data been received from the server ok?
Does clicking a button trigger the expected response?
Do click events work on dynamically loaded html content?
Does the app respond correctly to changes in hash/push-state urls?
I would imagine the testing has to be directly integrated into my app so as to have access to specific JS objects, work with session specific data and respond to changes in push state URLs.
How can I integrate QUnit or Jasmine (or other suggestions) into my modular app to unit test such features?
Unit testing is really simple.
You make a test HTML page. You include QUnit/NodeUnit/Jasmine/TestLibraryOfChoice
You then use requireJS and load one of your javascript modules,
and you simply test the exported object or function. That means testing the valid inputs of your module and asserting the outputs are correct.
You may have to mock out ajax and write HTML mocks
Dojo Objective Harness (DOH) is a very good unit test framework, which is browser agnostic and supports testing asynchronous functions, see here for a walkthrough guide.
However, from your test cases it looks like you want something more like an integration test?
If so Selenium is a good browser automation tool.
Crucially, neither of these tools will require you to modify your code (unless you find bugs :))
If you want to see an example where requireJS based modules are unit tested with QUnit, download the javascript reference architecture at http://boilerplatejs.org.
Disclaimer: I'm the main author of it.

Categories