Dynamically-populated <select> not populated during testing with Codeception - html

I am relatively new to Codeception and am trying to perform acceptance testing of a form using it and Selenium WebDriver with Firefox. The form (available at http://www.brighton-hove.gov.uk/content/parking-and-travel/parking/find-your-parking-zone ) consists primarily of a text box and an auto-populated which is inserted into the DOM in the event that the input into the text box results in multiple matches; each field also has a submit button.
The issue I am experiencing is that, when tested normally in Firefox the behaves as expected and is auto-populated in cases where the initial, textual search returns multiple matches (for example, entering any Brighton postcode, although the particular scenario is to search for 'Brighton Town Hall, Bartholomew Square', which returns 3 results). However, when attempting to test via Codeception (either running a complete test or attempting each step via the console), the gets inserted into the DOM but never appears to be populated with real results (the only element it contains being 'Please select your address...').
My test steps are as follows:
$I->amOnUrl('http://www.brighton-hove.gov.uk/content/parking-and-travel/parking/find-your-parking-zone');
$I->fillField('Enter your postcode or house number and street','Brighton Town Hall, Bartholomew Square');
// XPath is used here as the form elements' 'id's, 'class'es and 'name's are auto-generated (the one above just happens to have a label).
$I->click("//div[#id='achieveform']/form/div/div/div[1]/div[1]/div/div[3]/div/input[#type='submit' and #value='Search'])";
// I've also tried using 'submitForm(...)' here, rather than just clicking the button.
// Wait an unnecessarily long amount of time in the hope that the dropdown appears and is also populated...
$I->waitForElement("//div[#id='achieveform']/form/div/div/div[1]/div[1]/div/div[7]/div/div[3]/div/div[1]/span/select", 5);
// The first option is there...
$I->seeElementInDOM("//div[#id='achieveform']/form/div/div/div[1]/div[1]/div/div[7]/div/div[3]/div/div[1]/span/select/option[1]");
// ...but it doesn't have 4 options, as expected.
$I->seeNumberOfElements("//div[#id='achieveform']/form/div/div/div[1]/div[1]/div/div[7]/div/div[3]/div/div[1]/span/select/option", 4);
Although the test I am looking to perform is essentially black-box my next course of action is to attempt to look into tracing the form submissions and DOM updates, even though that level of knowledge of the underlying structure of the system should not be necessary. Am I overlooking something simple? Any pointers would be appreciated.

Apologies, it turns out it wasn't anything to do with Codecepetion after all: the issue was partly to do with the backend logic behind the search form (which doesn't seem to like the comma) and partly due to me for not noticing that the behaviour with the empty dropdown did actually also occur when performing the same actions outside of Codeception.
Moderators: this thread can be closed/removed (as the issue was a non-issue within the context of Codeception) now.

Seems you are not filling value in the right field or the text input field of the search box:
instead of:
$I->fillField('Enter your postcode or house number and street','Brighton Town Hall, Bartholomew Square');
Use:
$I->fillField('.dataelr input', "Your Value here");
Hope it helps.

Related

How do I keep a user from double clicking a link in an email?

When users request a password reset, they get an email with a link to generate a password reset code. This link is valid for 24 hours and can be re-used within the 24 hours to generate a new code if the first is lost or forgotten. When users double click the link, two codes are getting generated, leading to user confusion about which to use (the second code invalidates the first code with the way it has been developed).
Since the link in the email is just an html a tag, I'm not sure how I can keep users from double clicking the link.
This sounds like you're facing the XY problem. Your actual issue is that users get confused by visits in a quick succession causing a code that was just generated to be invalid, rather than the fact that the link can be clicked twice.
From a security point of view, these kind of links should really be single-use, and the user should request a new e-mail if they want to perform the action again. Assuming this is something you're forced to do, I believe the best compromise would be to limit code generation to a time frame, so visits within, let's say, 5-10 seconds would result in the same code being shown to the user, based on the server's time.
Implementing any CSS based solution for this that'd work across every e-mail client out there is challenging enough (if at all possible), and I doubt any self-respecting e-mail client is going to let you run any sort of JavaScript to intercept the event.
The following works in a modern browser on an actual web page, but this is not just a bad idea, it's also probably not going to work if you try to use it in an e-mail. I'm providing it here just for the sake of completeness, showing that it's somewhat possible, but please do not rely on this to fix the underlying issue.
<style>a:focus { pointer-events: none }</style>
<p>This is some text, here's a link you can't double click by the way.</p>

How do I automate tab selection on a website

Here is the website I am trying to access. I dont want the default tab (Day) though, I want to select the Season tab
https://www.eex.com/en/market-data/power/futures/uk-financial-futures#!/2017/05/23
The link appears to be exactly the same whichever tab is chose making differentiation impossible as far as I can tell.
Any help on this would be much appreciated, using whichever programming method and language is appropriate.
Kind Regards
Barry Walsh
The URL does not change since this is an ajax request, which you can see from MarketDataTableAController's getPageData function. You can read about them here https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started
Ive inspected your html and you seem to be using angular. On further inpection you can see that the tabs have ng-click="setActiveTab(tab)" attribute on them. So whenever user clicks, this function gets executed. It is a matter of using this function with the appropriate tab object to get the content to change. You for example could put setActiveTab(tab) into your controller init method since setActiveTab() calls the forementioned getPageData() function to update the page.
Also the tab you are looking for is page.tabs[5] ($parent.page.tabs[5] if referring from TabController) since this is the tab with the label of season. Pass that to setActiveTab() and it should show you the season instead.
However this might not be a good solution since the tab array ordering might change. Then you would need to loop over all objects in page.tabs and see if tab.label === "Season" and pass that in the function instead or better yet use the $filter service provided by angular which would look more cleaner.
Your code source also seems to be minimized and its not very easy to read.

VS 2015 Razor Autocomplete/Intellisense dropdown hides immediately after dropdown

In VS 2015, only when in Razor (.cshtml) files, roughly half of the time the autocomplete/suggestion list/intellisense doesn't work correctly (sorry, not sure the actual term... when you type an object and hit . and the list of properties and methods shows to select from)
The behavior is that when I hit ., the list popups up for a fraction of a second and then closes. It happens so fast I try to do a quick Backspace, ., Backspace, . cycle a few times to at least see the name I need, but I usually cant' get it and end up having to find the exact name elsewhere from code. Extremely irritating...
It happens sporadically with no real pattern I can find. Here's patterns that I've ruled out:
The file that's open doesn't seem to matter.
Whether or not I close/reopen the file doesn't seem to matter
Whether I navigate to another file and back doesn't seem to matter
It will work/not work multiple times on and off throughout the same file
It doesn't seem to be relevant to any particular object/property/method
I've checked all my options (there doesn't seem to be Text Editing options for Razor?), have tried clearing caches, the reloading solution/projects, restarting VS, all of which seem to still provide no pattern.
Has anyone come across this and have any ideas of where else I can look to fix it?
Example
Here's an extremely simple example... new project, very little code/files, very simple view. Where the Model. stops, I should have the usual base methods, and an 'Items' collection. It pops up for a split second then disappears... no lambdas/complex view parsing involved (this is reproducible as well):
Update: Patterns
Things I've noticed:
If I'm entering a #model ns.ns.ns.type, it rarely happens toward the "base" end of the namespaces. It's as I get further towards the type that it happens. This one is intermittent.
In some cases, it works perfectly fine, every single time. For example, I often use DevExpress tools, and have never seen the behavior on any of their extensions (so, #Html.DevExpress(). (and other similar, not necessarily DevEx models) will never cause a problem)
It happens almost all the time when I'm accessing my #Model (which is where I most want it!). I've found some cases where this is reproducible every time (see above example), but it's about 90%+
Occasionally, as I work through the object tree, one will fail while the next works (ex: #models ProjName.Web.App.Subscriptions.Models.AccountCreateVM... it might fail on Subscriptions but work fine on Models)
Occasionally, beginning to type the name within autocomplete kicks it back into gear and it starts working again. In the above example, starting to type Acc for AccountCreateVM causes it to start working again.
I haven't found the root cause, but in all cases, CTRL+SPACE works. This isn't the best, but light years better than nothing at all.
(this shortcut is not one I've used in the past, so this is likely standard behavior, but...) If you're at the dot Model. and autocomplete list disappears, CTRL+SPACE consistently brings it back up, and when it does come back, it stays! If there's only one possible autocomplete member, it'll auto-fill the member for you upon CTRL+SPACE
This happens for me all throughout VS2015 during lambda statements.
It happens when editing code "mid-document", as in, if there is anything besides a ) or } following where I'm typing. VS appears to be struggling to tell where the current statement ends & the next statement begins.
The following code will consistently fail to trigger Intellisense at the period, even when explicitly invoked.
var subset = initialSet.Where(x => x.
var result = new Whatever();
In Razor, it is very common to be editing code between existing text and using lambda statements:
<strong>#Html.DisplayFor(m => m.</strong>
This is probably why you only experience this in Razor.
The way I work around this bug is just to write the ) to close the method.
var subset = initialSet.Where(x => x.)
var result = new Whatever();
<strong>#Html.DisplayFor(m => m.)</strong>
Intellisense can then be triggered on the period.
If you're using a method that requires a minimum of more than just the lambda (like RadioButtonFor), you'll also need to put in a comma for each of the extra parameters.
<strong>#Html.RadioButtonFor(m => m.,)</strong>
If Intellisense is appearing, but immediately disappearing again, the best solution I've found so far is to just type a few letters of any known member, then using Ctrl-Left to skip back to the period, and trigger Intellisense again (Ctrl-Space or backspace-retype). This usually gets it to appear and stay. You'll have to delete the characters you typed afterwards, which can be frustrating.
Just make sure the ) does not touch the text you are editing, and the popup will stay up.
Instead of...
#Html.Partial("ManageGrid", Model.)
Use...
#Html.Partial("ManageGrid", Model. )
The intellisense seems to get confused by touching close parenthesis. Not ideal, but this was the only way I could get it to work for me consistently.
In my specific case, i was able to solve the problem by installing the latest version Microsoft ASP.NET and Web Tools.
https://marketplace.visualstudio.com/items?itemName=JacquesEloff.MicrosoftASPNETandWebTools-9689
Once I installed it, the problem was gone. It is likely that this update fixed something that could be fixed with an older version, but either way I'm happy.
(I found this in Visual Studio under Tools->Extensions and Updates...->Updates->Visual Studio Gallery)
I had the same error and I fixed it by deleting all the files of the component model cache.
This is the path:
Users\YourName\AppData\Local\Microsoft\VisualStudio\14.0\ComponentModelCache
Hope that helps
I use ctrl+j as a temporary solution when I know the content.
Or keep writing without right parenthesis can use the completion:
#Html.LabelFor(m => m.Name
Whenever this annoying thing happens to me, I just put an extra dot and then it works. I have to put the extra dot every time. For example, if I write this and intellisence flashes and disappears:
#Html.TextBoxFor(m => m.
then I just do this:
#Html.TextBoxFor(m => m..
And intellisense will now show after first dot. I have made this a habit until MS has a fix for it.
Instead of...
#Html.Partial("ManageGrid", Model.)
Use...
#Html.Partial("ManageGrid", Model.

Get value of textbox in a table (GAS)

I know that this is something discussed sooo many times, but I can't get the value of a textbox that is placed in a table. I know how to get the value of a textbox (e.parameter.textBoxName), usually it's working without any problems.
The only difference now is that I have a gadget containing 5 tabs, each with some intro text and a table. Each table contains approximately 30 rows, each with two textboxes and a button to submit the value of two textboxes in the specific row to a spreadsheet. Everything is working fine, all the names (and IDs as well) are unique, but the problem is that when I submit textboxes, I get "undefined" (in my spreadsheet).
I guess the problem lays somewhere in the complexity of the script, so this:
function buttonClick(e) {
var app = UiApp.getActiveApplication();
var theValue = e.parameter.textBoxName;
...something...
}
..is simply not enough to define which textbox it is. However I'm getting the button ID without any problem with
var buttId = new String(e.parameter.source);
I'm trying to get my head around this for a couple of days without any results. I'm not that good with GAS and I'm completely out when it comes to objective programming. Do you have some ideas how to get this value? I can get the ID of the table if that helps, but what to use then?
Thank you very much in advance!
EDIT:
I tried .addCallbackElement(textbox) to the textbox - I'm getting an error. I tried .addCallbackElement(textbox) to the submit button together with .addCallbackElement(button) and I'm still getting "undefined".
the callbackElement must be added to the handler, not to the widget nor to the button.
The easiest (and safest) way to get it done correctly is to choose the highest level parent as callbackElement.
I your case it would probably be the tab panel or eventually another panel that contains your 5 tabs if you used one.
Note also that there might be really a lot of widgets in the same UI without causing any issue... I have an app with about 200 textBoxes that works flawlessly and I'm not aware of any limit nor if a limit even exists...

Rendering 20 large identical listBoxes

I have an HTML table with rows (20 rows).
Every row has a listbox of countries (about 250 countries) that are filled using a single dataset from the database.
Loading time is quick enough, but rendering time is really a mess.
Is there any way I can speed the rendering of those listboxes?
You could load it only once, and then copy the DOM element everywhere you need it...
I'm not sure if this would improve a lot since it would rely more on the user's computer, but I guess it's worth trying if it's too slow the way it is right now.
edit: here's how I'd do it. Use with caution, I haven't tested it and there is most likely tons of errors with this code, it's just to give you an idea of what I was saying.
<mylistbox id="listboxtemplate"> ... </>
<div class="thisPlaceNeedsAListbox"></div>
<div class="thisPlaceNeedsAListbox"></div>
<div class="thisPlaceNeedsAListbox"></div>
on document ready, using jquery:
jQuery(".thisPlaceNeedsAListbox").append( jQuery("#listboxtemplate").clone() )
You could try to add next select box only after user has selected previous one (using JavaScript).
I'm quite sure that you can rethink the form or the process, but I can't suggest anything specific since you haven't given enough information. For example depending on situation you could use multi-select or some fancy JavaScript widget.
EDIT based on your comment:
Then how about serving the table without selects. And if user double clicks on a country field you change the text element to select element using javascript. And once user has selected the country you can change back to text element. You can submit results back to server using Ajax (after user has selected the country) or using hidden fields a submit button. This way DOM will never contain more then 1 select element.
You can pass countries to javascript using inline JSON object/array (in script tags). To make things even more faster after user has edited the first element, just hide (css: display: none;) the first build select element and clone/move it around each time user wants to edit a row.
As you can see there are a lot of paths you can take using this approach, it all depends how much you want to optimize/work on it.