Difference between protractor locators - protractor

I was going through the protractor guide here: https://github.com/angular/protractor/blob/master/docs/api.md#api-protractor
It says in order to locate a element, I could use
var temp = element(by.css("someclass"));
or alternatively
var temp1 = ptor.findElement(protractor.By.css('someclass'))
Which kind of locator is to be used when ? Could someone pls clarify

They are the same. element is the preferred syntax because it is shorter and because you can chain locators and use some fancy protractor features. Protractor extends the webdriver api and that is why you can use the same functions that you would use in plain webdriver.
For example, the following expressions are equivalent:
ptor.findElement(by.css('.foo')).getText()
element(by.css('.foo')).getText()
$('.foo').getText()
To look for multiple elements use:
ptor.findElements(by.css('.foo'))
element.all(by.css('.foo'))
$$('.foo')
There are many examples in the api.md document:
https://github.com/angular/protractor/blob/master/docs/api.md#elementfinderprototypeelement

The difference between ptor.findElement and element is that the first should be used pages without Angular while the second is used on pages with Angular. This is related to how protractor syncs with Angular. The first returns a WebDriver WebElement, the second returns a Protractor ElementFinder.
However to address your question directly, there is no difference between the locators returned by by.css and protractor.By.css.
The two are equivalent. The object referenced by the global by object is the same as the the object referenced by protractor.By.
From Protractor's runner.js:
global.by = global.By = protractor.By;
There are two versions of the API. The old version used protractor.By, whereas the new version uses by. You may often see the old style but if you are in doubt, you can use the new style and be sure nothing unexpected will happen.

Related

Node.CloneNode() not a function -dom-to-image.js

I want to create a .png file of a HTML page in angularjs and download it. For this I'm currently using dom-to-image.js and using the domToImage.toBlob function and passing the node element to it. But internally when it goes to dom-to-image.js it throws the error:
node.cloneNode() is not a function
Can anyone please assist me here?
Thanks
This error arises when you attempt to call cloneNode() on anything other than a single DOM node.
In this case, the error is coming from the dom-to-image library, which calls that method internally.
Note that without a code snippet, its hard to identify the precise issue with your code, but the point is, when you call domtoimage.toBlob(), you need to supply a single DOM node.
So double check what you are calling it with. If you are selecting by class, for instance, you could end up with more than one element.
Its best practice to be precise with which node you want to convert to a blob - use the id attribute, like this:
domtoimage.toBlob(document.getElementById('element')).then(...)
where element is the id of your target node.
Its also possible you're selecting with angular.element() or even using jQuery directly.
In both cases, this returns an Object -- which you can't call cloneNode() on.
Also note the following from the Angular docs for angular.element():
Note: All element references in AngularJS are always wrapped with jQuery or jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.
Which means you would observe the same behavior in both cases, e.g. both of these:
domtoimage.toBlob($('#element')).then(...)
domtoimage.toBlob(angular.element('#element')).then(...)
would result in the error you see. You can index the Object before supplying it to domtoimage.toBlob(), perhaps like this:
domtoimage.toBlob($('#element')[0]).then(...)
domtoimage.toBlob(angular.element('#element')[0]).then(...)
and that would also work.
Also check out this post about "cloneNode is not a function".

Testcafe Selector to identify element inside the specific component of DOM Structure

How to convert the below Relative path to TestCafe Selector?
//a[contains(#name,'indent')]/parent::div//span[contains(text(),'Follow')]
If I try the above one, it recognizes specific DOM Component which contains multiple elements and one of those is 'Follow'.
how to achieve this using TestCafe Selectors.
I did not succeeded with the below one :
Selector('a').withAttribute('#name','indent').parent('div').child('span').contains('Follow')
Selector('a').withAttribute('#name','indent').parent('div').child('span').withText('Follow')
I checked your code and found a couple of possible causes, which can lead to the issue.
TestCafe Selectors do not have the contains method so the first example is incorrect.
Though I don't know your html structure, I can currently assume that there is no need to pass the # char in the attribute argument.
Thus your second example looks valid excepting the # char.
If this recommendation does not help, please provide us with a working example that shows the issue and create a separate bug report in the TestCafe repository using the following form

i18n in Symfony Forms

Is there any way I can use the format_number_choice function inside of a actions file. In fact I need to use it for a Form error message.
'max_size' => 'File is too large (maximum is %max_size% bytes).',
In English it's simply "bytes", but in other languages the syntax changes after a certain value (for example if the number is greater than 20 it's: "20 of bytes").
I can use parenthesis, of course, but if the framework offers support for doing this specific thing, why not to use it?!
The way it's currently implemented in the 1.4 branch, you can define only one translation per message using il18n XML files.
What you could do is create a custom validator which inherits the current validator (sfValidatorFile in your example) and does the size checking in the doClean method before calling its parent's method.
I suggest you take a look at the source to see how it works : sfValidatorFile
The correct way to handle number ranges for translation is explained here in the Definitive Guide. I won't reproduce it here as the documentation itself is clear and concise. Note however that the string is not extracted automatically by the i18n-extract task, so you need to add it manually - again, the documentation explains this.
So yes, you can use the format_number_choice() function inside an action - you just need to load the helper inside the action like this:
sfContext::getInstance()->getConfiguration()->loadHelpers('I18N');

How do I associate a CoffeeScript file with a view?

Just installed rails 3.1 rc1 and am trying to grok the best way to manage javascript with the new asset pipeline
By default all coffeescript is compiled into a single application.js file, this is a good thing.
Each seperate coffee script file is appended to the js file and wrapped in an anonymous function which is executed via the call method
A common scenario would be to use some jquery to turn various forms into ajax forms, update UI, etc...
Many of these scripts will be specific to a controller or action, I am trying to grok the 'conventional' way to handle this,
since everything is wrapped in an anonymous function how do I only execute just
the code for a particular controller / action, by default all of the anonymous functions are being executed
I did play around with some hacks where I load the controller and action name into js variables and then in
coffeescript check those to conditionally run code, I don't like that very much
my initial thought was that each coffee file would contain a js namespace/object and I would call the specific ones from the view,
going to spike this using the default_bare = true configuration
see How can I use option "--bare" in Rails 3.1 for CoffeeScript?
EDIT
Looking around some more: this looks like it might be the correct approach - "Can't find variable" error with Rails 3.1 and Coffeescript
There are two common approaches:
Make behavior conditional on the presence of a particular element. For instance, code to run a signup sheet should be prefaced with something like
if $('#signup').length > 0
Make behavior conditional on a class on the body element. You can set the body class using ERB. This is often desirable for stylesheets as well. The code would be something like
if $('body').hasClass 'user'
gistyle is a simple gem that helps you running action-specific javascript codes.
By following its setup, you set some data attributes in your body element, representing the current controller and action names. Then it will only call that action when the corresponding view is loaded.

Javadoc on CoffeeScript?

I'm new to CoffeeScript and seems that I can't find any document generator for CoffeeScript using Javadoc syntax. The only one I could find is available as a patch to the CoffeeScript compiler.
So, what do you use to generate documentation from Javadoc comment on CoffeeScript or how do you document your function arguments and return values?
So, JavaDoc syntax has never really caught on with JavaScript developers. There are those who use something like it—notably Google—but it's kind of at odds with JS, which doesn't have static typing and allows any number of arguments to any function.
If you want to create beautiful documentation with CoffeeScript, the standard is Docco (its home page is an excellent example). If you want to create JavaDoc-style comments for every function... well, you'll have to create them by hand, and escape them with backticks.
Alternatively, you could work in CoffeeScript until your code is release-ready, then document the resulting JavaScript.
Docco is great for prozedural coding style. If you want to document an API, coffeedoc is for you.
People looking forward to using javadoc style documentation in coffeescript can checkout codo ( http://netzpirat.github.com/codo/ ) which provides support for a subset of javadoc and automatically infers class names, function names and parameters from source code.
I'm using YUIDoc. I can add comments using a syntax similar to Javadoc to my classes, methods and events. The documentation gets output as html/css files and you can even customize the page layout.
Check this documentation example: http://yui.github.com/yuidoc/api/
PS: It relies on Node.JS and you need to install the package yuidocjs
npm install yuidocjs -g