Testing angular forms - javascript

I am trying to test an angular app in protrator and I do not understand something.
I put this line there
beforeEach(function() {
browser.get('http://juliemr.github.io/protractor-demo/');
});
And I want to refenrence the elements of an HTML form using this line:
fdescribe('Protractor Demo App', function() {
var goButton = element(by.id('gobutton'));
...and test its result
In protractor we do not put the test files corresponding to a specific .ts file in its folder, so this test searches in the whole project for an id gobutton or it searches for an id gobutton that belongs specifically to the link that I have put on browser.get()??
And my next question is if the page I wanna test requires a login, can I just use browser.get url of this page and test the elements or I should do the part of logging during my test?
And is it normal if my browser closes itself afterexecuting one test, or it should stay opened?

This is a lot of questions ;)
Protractor will search the whole DOM for the element's id. Even if you work with the mentioned *.po.ts files in the component folders, they'll eventually only deliver the elements id represented by a string you then search via element(by.id()).
If a login is required, you'll have to consider it during your test. I doubt that you can bypass the login mechanism, except the login can be switched off on the testing stage and switched on on the production stage.
Yes, it is the standard behavior of Protractor to close the browser after having finished the test. This is because you have your protocol file afterwards.

This is how my protractor.conf.js looks like. The given path target is located on the level of /src.
let HtmlScreenshotReporter = require('protractor-jasmine2-screenshot-reporter');
// always create test-report.html, screen shots only in case of failures
let reporter = new HtmlScreenshotReporter({
dest: 'target/test-screenshots',
filename: 'test-report.html',
reportOnlyFailedSpecs: false,
captureOnlyFailedSpecs: true,
pathBuilder: function (currentSpec, suites, browserCapabilities) {
// will return chrome/your-spec-name.png
return browserCapabilities.get('browserName') + '/' + currentSpec.fullName;
}
});
exports.config = {
...
beforeLaunch: function () {
return new Promise(function (resolve) {
reporter.beforeLaunch(resolve);
});
}

Related

How to move from jest with user journey like tests to #playwright/test using fixtures?

Personally I see playwright as a tool that goes into the direction of system/end-to-end tests. So I used playwright + jest to build-up user journeys and integrated them in a CI/CD process.
Since playwright created it's own test runner with useful features like taking videos and trace on failures, it would make sense to switch from jest to #playwright/test. On their home page playwright recommends to use test fixtures so I definitly want to include them in the switch.
In the following I will take amazon as an example.
With playwright + jest the first thing that I did was to create a function for generic setup of the environment:
function setupSuite({ browserOptions, userConfig }){
// create playwright browser and use browserOptions as overrides
// create page from browser
// register self-implemented trace and screenshot reporters to page
// go to baseUrl of current environment (e.g. local, branch etc..)
// click on cookie banner, since it's blocking the UI
// create a user based on userConfig (e.g. user has amazon prime user? payment options? etc.)
// return { browser, page, user, ... }
}
And of course a function to clean up everything again:
function teardownSuite(suite){
// close browser
// delete user
// etc..
}
Then I would use a file for each user journey. In case of amazon a user journey could be the successful processing of an order:
describe("Successful Order", () => {
let suite
beforeAll(async () => {
const userConfig = { isPrime: false, paymentOptions: [ "paypal", "visa" ] }
suite = await setupBrowser({ userConfig })
// I actually extracted that logic in a function to be able to use it in other tests too,
// but just want to make clear whats happening here
const { page, user } = suite
await page.fill(".login-username-input", user.username)
await page.fill(".login-password-input", user.password)
await page.click(".login-submit-button")
})
afterAll(() => teardownSuite(suite))
test("search for toothbrush with suggestions", async () => {
const { page } = suite
await page.fill(".search-input", "tooth")
await page.click("text='toothbrush")
// hit enter
// do some assertions to check if the search was really successful
})
test("click on first item and add to chart", async () => {
// page actions and assertions
})
test("go back, click on second item and add to chart", async () => {
// page actions and assertions
})
test("go to chart and pay", async () => {
// page actions and assertions
})
test("check order confirmation mail", async () => {
// page actions and assertions
})
})
As you can see I split up my test in logical parts to make it more readable and also to see at which step (test block) it failed.
What would be the best way to migrate this to #playwright/test + fixtures?
How would you migrate setupSuite / teardownSuite ? Yes you could use a fixture, but setupSuite expects arguments like the userConfig . Is it possible to have parameterized fixtures?
How would you structure tests with fixtures? If you want to simulate complete user journey the tests are getting bigger than just testing a login for example. A test block would then have a lot of lines without the possibility to structure them.
Is it possible to setup a page so it's shared accross all tests? The beforeAll hook doesn't receive any page and the each test block always receives its own page. This means that there is no connection between test blocks. If you create a page manually in beforeAll and use the same page instance in every test it would probably be a bad practice and video and tracing would probably not work.. so what can be done here?
Are user journey like tests actually bad? I feel like they can't be combined well with the fixture approach of playwright as mentioned in the docs. Fixtures in playwright feel like very data-driven which doesn't really fit to end-to-end testing IMO.

My JSLink script will not work

I am attempting to use JSLink ..finally.. and I am having some trouble that I cannot seem to straighten out. For my first venture down the rabbit hole I chose something super simple for use as proof of concept. So I looked up a tutorial and came up with a simple script to draw a box around the Title field of each entry and style the text. I cannot get this to work. Is there any chance you can take a look at this code for me? I used the following tokens in the JSLink box.
~sitecollection/site/folder/folder/file.js
And
~site/folder/folder/file.js
The .js file is stored on the same site as the List View WebPart I am attempting to modify. The list only has the default “Title” column.
(function () {
var overrideContext = {};
overrideContext.Templates = {};
overrideContext.Templates.Item = overrideTemplate;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext);
}) ();
function overrideTemplate(ctx) {
return “<div style=’font-size:40px;border:solid 3px black;margin-bottom:6px;padding:4px;width:200px;’>” + ctx.CurrentItem.Title + “</div>”;
}
It looks as though you are attempting to override the context (ctx) item itself, where you actually just want to override the list field and the list view in which the field is displayed. Make sense?
Firstly, change overrideContext.Templates.Item to overrideContext.Templates.Fields :
(function () {
var overrideContext = {};
overrideContext.Templates = {};
overrideContext.Templates.Fields = {
// Add field and point it to your rendering function
"Title": { "View": overrideTemplate },
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext);
}) ();
Then when the JSLink runs the renderer looks for the Title field in the List view, and applies your overrideTemplate function.
function overrideTemplate(ctx) {
return “<div style=’font-size:40px;border:solid 3px black;margin-bottom:6px;padding:4px;width:200px;’>” + ctx.CurrentItem.Title + “</div>”;
}
In terms of running multiple JSLinks on a SharePoint page, it is quite possible to run multiple JSLink scripts, they just need to be separated by the pipe '|' symbol. I use SharePoint Online a lot and I see the following formatting working all the time (sorry Sascha!).
~site/yourassetfolder/yourfilename.js | ~site/yourassetfolder/anotherfilename.js
You can run as many scripts concurrently as you want, just keep separating them with the pipe. I've seen this on prem also, however you might want to swap out '~sites' for '~sitecollection' and make sure the js files you are accessing are at the top level site in the site collection if you do so!
I have noticed when running multiple JSLinks on a list or page because they are all doing Client Side Rendering, too many will slow your page down. If this happens, you might want to consider combining them into one JSLink script so that the server only has to call one file to return to the client to do all the rendering needed for your list.
Hope this helps.

Umbraco 7: How can I refresh the tree view in my custom section?

I have created a custom section in umbraco to manage some data in an SQL database.
I can edit items OK but when adding I need to refresh the page to see my new row in the custom tree on the left.
How can I cause a refresh of my custom tree using AngularJS? My tree is called "clients".
I have tried debugging the code and looking at the source to find the event but I can't seem to work out how to do it.
Is there a method I can call on the umbTreeDirective somehow? Or an event to subscribe to?
I am fairly new to AngularJS and am struggling a little.
You're looking for the navigationService.
This line is example of a syncTree call:
navigationService.syncTree({ tree: 'clients', path: content.path, forceReload: false, activate: true });
Here's a contrived, spaghetti promised but full example:
angular.module("umbraco")
.directive('nowplaying', ['navigationService', 'contentResource', 'contentEditingHelper', function (navigationService, contentResource, contentEditingHelper) {
//spaghetti example to create new document
contentResource.getScaffold(parentId, alias)
.then(function (scaffold) {
var myDoc = scaffold;
myDoc.name = name;
//we have minimum to publish
contentResource.publish(myDoc, true, [''])
.then(function (content) {
$scope.newlyCreatedNode = content;
//Sync ('refresh') the tree!
navigationService.syncTree({ tree: 'clients', path: content.path, forceReload: false, activate: true });
});
});
}]);
All of the Belle documentation lives here. -I'm not sure it's actively maintained, i can say for certain that one or two signatures have changed since it was first posted. That aside, it's the best resource i know of to interact with all the umbraco exposed modules and services.

Casperjs Multiple Test Cases

I have written webui automated testing cases of a webUI using Casperjs.
it includes:
home.js (checks home page in log-in state)
premium.js (checks premium user in log-in state)
catagories.js (checks categories page in log-in state)
Favorite.js (checks favorite page in log-in state)
I can run these tests successfully.
Is there a way to run them all at once? So that I can test all the pages at once when I want?
I think you can do it by creating a single script and create different functions to test each of the functionalities. The following code may give some idea
casper.start();
var running = 1;
var home_js = function(){
//your casper steps in home.js
};
var premium_js = function(){
// your steps in premium.js
// at end set running = 0 to stop the execution
};
var controller = function(){
if(running==1){
home_js.call(this);
premium_js.call(this);
casper.run(controller);
}else{
this.exit();
}
}
casper.run(controller);

Allowing href links with hashes on them to bypass SammyJS routing

I have the following server-side URL mappings defined:
/main/item1
/main/item2
I've added SammyJS routing support so that I am able to do the following:
/main/item1#/ /* main view */
/main/item1#/topups /* topup view */
I've set up SammyJS like so:
s.app = Sammy(function() {
this.get('#/topups', function() {
console.log('Initializing topups view.');
});
this.get('#/', function() {
console.log('Initializing main view.');
});
});
The problem is, I have a summary section in my page that redirects to the topup view of a different "item". E.g., I am at the url /main/item1#/, and in this page, there exists a tag item 2's topups.
I expect to be redirected (page refresh) to the new URL, however, it seems like SammyJS is intercepting the /main/item2#/topups call and simply running the this.get('#/topups') route I've defined.
I expect that since the URL paths before the hash, /main/item1 and /main/item2 are different, the SammyJS routing won't be triggered.
Is there a way to prevent this behavior from happening in SammyJS?
I don't know much about Sammy but I can tell you from the way any router behaves, is that it catches the first match in the routing possibilities, and so, anything that ends with #/topups will be considered the same as long as it's after the hash sign.
so you better define the router this way:
this.get('#/topups/:item', function() {
console.log('Initializing topups view for item: '+ item);
})
and then call the pages with URLs like:
item 2's topups
I hope this is what you're looking for
I'm pretty sure using the full URL redirect you.
Item 2 top ups for the lazy coder
However, that will cause the page to reload. If you modify Labib's answer you can have an even better solution:
this.get('#/topups/:item', function () {
console.log('Doing some post processing on current item');
console.log('Now redirecting you to ' + this.params.item);
window.location.href = 'http://example.com/menu/# + this.params.item +#/topups';
});
Again this will cause the page to reload, but if you do not mind that, then just either method.
NOTE: Sammy will also check form submission for you. This trips me up EVERY time I use it. This post has the solution.

Categories