I am trying to automate a work flow process .In this,I need to click on a link positioned in any of the rows of table.Thing is all links available in all rows have same element ID and in the source code I have a java script like " ("Element ID" # Onclick..java script****:).....SO here after clicking it is connecting one form to another form by inputting some value in java script code and also one value in java script dynamically changes.How do I click on that link now?Is there any solution using xpath or so...to exactly click on that link based on CSS classID or so...Please help me out..Main problem is...all links in rows have same element ID and dynamically changing java script .
I am trying to use selenium.focus() and selenium.clickAndwait().But these are helpless.as it is not able to identify link ID only.
The best way to do this would be with xpath.
Something like //*[#onclick='javascript'] will work but this can make the tests extremely flaky because if the inline javascript changes or if its removed in preference of addEventListener to the element.
something like //*[#class='cssClass'] will work. I think that you will need to speak to the developers and ask them to help make it more testable.
Related
I created a click event in adobe launch which will capture the value of the link and send it to analytics. I have created a data element for saving the value and in my DOM I am saving value in local storage.
Local storage code:
$('.card').click(function() {
var name = $(this).text();
localStorage.setItem('productName', name);
});
My problem is when I click the first link no value got saved, but after when I click second link it saves the value of first link and on third link saves value of second link and so on. I want to save current link value in evar3 variable.
Data element:
Rule:
Set variables:
Thanks,
Harshit
I'm scratching my head a little bit about why your jQuery selector doesn't match your Rule selector, but that's probably not immediately related or relevant, considering you said you are seeing data pop, in general, so at face value, I'm going to ignore that.
But in general, it sounds like your jQuery code is getting executed after the Rule is evaluated, so it's effectively one step behind. I'm not sure there's much if anything you can do about that if you aim to keep two separate click event listeners like this.
You're going to have to restructure to have one chain off the other (which I don't think is actually feasible with jQuery > Launch as-is. Maybe if you write two separate custom code blocks with promise chaining but that kind of sidesteps Launch and IMO is over-complicating things to begin with (see below)). Better yet, merge them into a single click event listener. On that note..
Why do you have two separate click event listeners? Is the sole reason for this to pass off the link text? Because you can reference the clicked element in the Launch Rule itself.
You should be able to reference %this.innerText% in the Set Variables fields. Or you can reference this object in custom code boxes within the Rule.
IOW at face value I don't see why you need or should be creating/using that jQuery listener or pushing to local storage like that.
Update:
You commented the following:
I tried with %this.innerText% it is also not showing current values. I
am pushing the value first to local storage because my link values are
generating on runtime through an API. They are not hardcoded. I am
also trying to figure out why my rule is getting fired before my
jquery is evaluated. But when I check in console using
_satellite.getVar('Product Name'); it shows me the correct value, but in debugger console value is wrong. Can you show me the way you want
to create rule to getting it fired correctly ? Thanks,
Okay so your link values are generated runtime through an API call? Well okay now that sounds like where the (timing) issue is, and it's the same issue in principle I mentioned you prolly had between the jQuery and Launch code. Assuming you can't change this dynamic link functionality, you have two options:
1. Explicitly trigger a launch rule (direct call rule) in a callback from the API code that's generating the link values.
This is the better method, because you won't have race condition issues with your API vs. link tracking code. The biggest caveat about this method though is that it requires requires you to actively add code to the site, which may or may not be feasible for you.
I have no idea what your code for generating the link looks like, but presumably it's some ajax call and generated from the success callback. So in the callback, you'd add a line of code something like this:
_satellite.track('product_image_click', {
text : elem.innerText
});
Again, I don't know what your API code that generates the link looks like, but presumably you have within it some element object you append to or update the DOM, so for this example, I will refer to that as elem.
'product_image_click' - This is the value you use for the direct call rule identifier in the interface, e.g. :
And then _satellite.track() call also includes an object payload in 2nd argument that you can pass to the direct call rule. So in the code above, I set a property named text and give it a value of elem.innerText.
Then, within the direct call rule, where you set variables, the data you passed can be referenced from event.details object within custom code box (e.g. event.details.text), or using % syntax within the interface fields (e.g. %event.details.text%).
2. Make use of setTimeout to delay evaluating the link click.
The one advantage of this method over option #1 is that it is passive. You don't have to add code directly to your site to make it work.
However, this is the shadier option, because you don't really know how long it will take for your link to be generated. But generally speaking, if you can determine it takes on average say 250ms for the link generation API to do its thing, and you set the timeout to be called at say 300-500ms, then you will probably be okay most of the time. However, it's never a 100% guarantee.
In addition, if clicking on the link ultimately redirects the visitor to another page, then this solution will likely not work for you at all, since the browser will almost certainly have navigated before this has a chance to execute. Because of this, I normally I wouldn't even mention this as an option, but since you mentioned this link involves an API that generates the link values when clicked, I figured maybe this isn't a navigation / redirect link, so maybe this is an option you can go for, if you can't do option #1.
First, create a direct call rule the same as shown in option #1. This will be the rule that receives the link text and makes the Adobe Analytics (or whatever other marketing tag) calls.
Then, create a separate rule as a click event, similar to what you are currently trying to do (listening for the link click, based on your css selector). In this rule, you won't be setting any AA variables. Instead, add a custom js box with code like this:
var elem = this;
(function (elem) {
window.setTimeout(function() {
_satellite.track('product_image_click', {
text : elem.innerText
});
}, 500);
})(elem);
So when the rule is triggered, it will create a setTimeout callback to call the first rule, passing the link text in the payload. And.. hopefully the 500ms timeout shown in the code example is enough time for the API to do its thing. You may be able to adjust it up or down.
Rather than defining it in Data Element I would say its better to keep it directly in the Rule itself. Please try with this %this.#text%.
Let me know if this helped.
The question in a nutshell: Is there a way to add forms dynamically to a aspx-page? I know how to add controls to an existing form, but how to add a whole form?
Bckground:
I am "forced" to work in Visual Studio 2008 and I want to create a controller, which builds a page depending from the list of elements a model gives it (e.g.: the list may contain a paragraph, an image, another paragraph, a parapgraph again, a form and so on).
This works fine for the first examples as I am able to add them to the inner-html of a div-container.
Thinking about ways to generate a form like this (innerHTML += form), I feel I'd be throwing the few possible advantages ASP I can see (compared to PHP) out of the window in terms of input validation and so on. But I can't find a way to generate a "real, server-run" form. The same goes for gridviews, but I guess the solution may be similar.
A possible workaround would be to create an empty form
<form runat="server" id="dummyForm">...
and add controls to it dynamically. The obvious(?) downside to this would be, that I couldn't change its position (at least I wouldn't know how) in relation to the other content elements.
Another downside would be that I would be limited to one form per page and that may or may not be sufficient. If it wasn't I would starting to add several empty dummy-forms and would start indexing them and all of that doesn't look very cool to me.
Is there a more elegant way to a solution?
TIA
Simon
You can't add more than once server side Form tag in single aspx file
(in run time or design time)
maybe this article help you to generate dynamic forms :
https://msdn.microsoft.com/en-us/library/aa479330.aspx
I'm making a plugin that gets the actual panel or text selection and runs a command on the cli with that value and some params that the user adds in a input.
The idea is to have a similar view than find-and-replace package, but from the first beginning I wasn't able to use space-pane-views for a error on jQuery.
So I decided to make it with React and as far as I was making everything was okayish, but I found 2 big problems.
First I understand what's the View of space-pan and all the ShadowDOM that uses, I feel that is not compatible with React at all, is some kind of big Model that gets data from the dom and from some methods.
So I created a <input /> and I figuret out that you can't interact as normal as a website with that input, doesn't have the hability of delete normally the text and you can't use the atom-text-editor styles into it.
in another hand I try to create a Custom Web Component with React like:
<atom-text-editor
{...this.props}
mini
tabindex='-1'
class={`${this.props.className}`}
data-grammar='text plain null-grammar'
data-encoding='utf8'
/>
and it works with inheriting the styles, but I can't access to the content of the Shadow DOM, neither add eventHandlers like onChange (onKeyPress works btw), this is basically a problem more than React that Atom, but is as far as I went in the intention to create a View in Atom.
Another option could be add draft-js from Fb, but it's a crazy idea for create a simple input.
Any idea to solve one of both problems?
Thanks!
If you add a normal input in React with className='native-key-bindings' the input contains the nativew key bindings, and you can attach the eventHandlers there.
I'm a backpacker and a programmer, trying to use the second skill to find openings in a full campsite. Rather than crawling fro scratch, I'm using the end-to-end testing framework nightwatch.js to navigate for me.
I've hit a roadblock, because nightwatch is having difficulty finding a specific element using css selectors.
Here are the elements and page:
Here is my test code:
Previous Attempts
My test code will click on the selection box with #permitTypeId. It will see that #permitTypeId option is visible. It will not see or click on any of the options when more specific values are specified. The five .click()'s are all css selectors I've already tried. None of the options are set to display:hidden or display:none. I have also tried all of the above without the .waitForElementToBeVisible() just in-case the waiting causes the dropdown to hide.
I've successfully clicked options from different dropdown menus on this website without any problem. Just this one is causing a headache.
The tests are running with the most current Selenium server and Firefox on Mac Yosemite.
tl;dr
Nightwatch.js/Selenium won't click on something from a dropdown menu.
The Path...
Cory got me thinking about jQuery and native DOM manipulation. Tried going that route and was successful selecting the correct option using Selenium's .execute() function:
.execute('document.getElementById("permitTypeId").options[1].selected=true')
However, it was not triggering the onchange event.
Saw this post which made me start thinking about using key-strokes and this one which suggested using arrow-keys to navigate down a <select> element to the option, then hitting enter.
...to the Solution
.click('select[id=permitTypeId]')
.keys(['\uE015', '\uE006'])
I've found that this is an issue with Firefox. Chrome and PhantomJS operate well clicking <option> tags.
you should be able to click like this way
browser.click('select[id="permitTypeId"] option[value="1451140610"]')
Additionally I was able to add a .click event for the specific option once I did a .click for the select. see my example below:
.click('select[name="timezone"]')
.pause(1000)
.click('option[value="America/Chicago"]') //selects the option but doesn't click
.pause(5000)
.keys(['\uE006']) //hits the enter key.
another solution:
.click('select[id="permitTypeId"]')
.waitForElementVisible("option[value='1451140610']")
.click("option[value='1451140610']")
Very simple way is to use .setValue('#element', 'value of option')
What is a good approach to avoiding Selenium tests being broken when dealing with the changing "Name" and "Id" attributes of a control that is rendered on a ASP.NET page using a master page? I want to avoid changing my tests when ASP.NET renders the web page's controls with different DOM identifiers.
http://www.stevetrefethen.com/blog/AutomatedTestingOfASPNETWebApplicationsUsingSelenium.aspx
Selenium
solves this problem using XPATH and
providing the ability to locate
controls based on XPATH expressions,
alleviating the need to hard code HTML
tag structure into a test script. For
example, the ASP.NET runtime may
render ID attributes that look like:
id="ctl00_cphContents_gridMaint_DataGrid"
Finding this control using an XPATH
expression can be simplified to
something like this:
table[contains(#id, "gridMaint")]
In the event the nesting of the
DataGrid changes the script will
continue to function properly as long
as table's ID contains the text
"gridMaint".
Another option is to use CSS locators. They're normally less fragile than XPath. For example, to target a div with a class of .myDiv you can use the locator "css=.myDiv". If the specified element has other classes the CSS locator will still work, although the XPath equivalent would change from "//div[#class='myDiv']" to "//div[contains(#class, 'myDiv']". Also, CSS locators tend to be faster than XPath across browsers.