I have a selenium UI test written with F# (using canopy selenium nuget package). I have a module that defines page selectors and helper functions. The page module is called by a test module. Within the test module, I am calling a function called 'handlemobimodals()', which runs four sub functions (if/else code blocks) that look for the existence of an element on a page and click on it, if it exists.
The problem I'm facing is that when the 'handlemobimodals()' function is called for a second time within the test, I get a Stack Overflow Exception (WebDriver Process is terminated due to StackOverflowException), right after its first sub function is called.
The function runs completely fine for the first time (called indirectly from another function earlier in the test), but fails the second time when called directly in the test. I'm pretty new to F# and I can't figure out how I'm causing a recursion in my test as the stackoverflow exception suggests.
Any insights would be greatly appreciated.
Snippet from Page Module:
module some_page
let isOKGotItDisplayed () =
isDisplayed <| "div.action-button.dismiss-overlay"
let clickOKGotit() =
if isOKGotItDisplayed() = true then
click "OK, GOT IT"
describe "OK, Got It clicked"
else describe "Got nothing"
let isGoToSearchDisplayed() =
isDisplayed <| "button:contains('Go to Search')"
let clickGoToSearch() =
if isGoToSearchDisplayed() = true then
click "button:contains('Go to Search')"
describe "go search button clicked"
else describe "Got nothing"
let isSkipDisplayed() =
isDisplayed <| "#uploadPhotos > div.continue.skip"
let clickSkip() =
if isSkipDisplayed() = true then
click "Skip"
describe "Skip link clicked"
else describe "Got nothing"
let mobiOkayGotItDisplayed () =
isDisplayed <| "Okay, got it"
let mobiOKGotit() =
if mobiOkayGotItDisplayed() = true then
click "Okay, got it"
describe "Okay, got it"
else describe "Got nothing"
let handleMobiModals() =
clickSkip()
clickOKGotit()
clickGoToSearch()
mobiOKGotit()
loginForPathAs user =
username << "somename"
paswword << "somepassword"
handleMobiModals()
Snippet from Test Module (note the first instance of the handleMobiModals function is called in the LoginforPathAs function, which is defined in the same page definition module):
module_sometest
open some_page
"Test 001: Log in and do something" &&& fun _ ->
newBrowser platform
loginForPathAs user1
displayed quicknoteSendButton
click quicknoteSendButton
handleMobiModals ()
displayed "Subscribe"
Note: Snippets are edited for simplicity and clarity.
It's not a direct answer, but I believe it would help to find the problem much easier. I did notice something that makes it somewhat difficult to debug this problem. You're calling multiple functions from another function, and calling this single function from a test. Splitting out these functions into separate tests and changing the tests into WIP mode should help to pinpoint your issue. There are a lot of possible points of failure within that one test.
For instance, you can use before(fun _ -> some function(s) here) or once(fun _ -> some function(s) here) within your context in Canopy to start a new browser and login, separating that part from the test.
This issue appears to have resolved itself. I believe my most recent auto-update for Chrome fixed the problem.
Related
When I bind a function to a button inside an accordion nothing happens upon clicking it. I have no idea what i'm doing wrong. :( Any thoughts?
def printTest():
print "The button worked!"
accord = Accordion(anim_duration=1.5, orientation='vertical')
specialButton = Button(text="click me", font_size='20sp', text_size=(1100, None), halign="center")
specialButton.bind(on_press=printTest():
item = AccordionItem(title="Hello World")
item.add_widget(specialButton)
accord.add_widget(item)
specialButton.bind(on_press=printTest():
This isn't valid syntax, is the colon a typo?
Either way, the problem is that you are calling printTest, not passing it as an argument.
Instead try
def printTest(*args):
print "The button worked!"
...and...
specialButton.bind(on_press=printTest)
The *args is important because the binding automatically passes some arguments.
I covered this in more detail here.
My understanding is that inside of a coffeescript function, "this" or "#" is equal to "window" (at least in the context of Rails). Why is it then that I can get this code to work:
window.googletag = window.googletag or {}
window.googletag.cmd = window.googletag.cmd or []
window.googletag.cmd.push ->
window.googletag.defineSlot('/1003175/ad-name-here', [336, 280], 'div-gpt-ad-1349373630997-0').addService(window.googletag.pubads())
window.googletag.pubads().enableSingleRequest()
window.googletag.enableServices()
but not this code
#googletag = #googletag or {}
#googletag.cmd = #googletag.cmd or []
#googletag.cmd.push ->
#googletag.defineSlot('/1003175/ad-name-here', [336, 280], 'div-gpt-ad-1349373630997-0').addService(#googletag.pubads())
#googletag.pubads().enableSingleRequest()
#googletag.enableServices()
When I place in my code alert(# == window) I get true.. if they are the same then why would one work but not the other? Is there not a more graceful way to write this code then appending window to every instance of the word googletag?
In coffeescript, the # is equivalent to this, but the value of this is dependent on your current scope within the code. In your example, alert(# == window) returns true because in that context this is the window. But when you use it in another context, for example inside a function definition (#googletag.cmd.push -> ...) then it will get the context of whatever scope that function is called from.
In the end this is not a coffeescript issue but a Javascript issue. I'd recommend reading up a bit more on this, it's a somewhat confusing concept at first.
Here's one article that helped me understand the concept better: http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/
I have a problem which i suppose must be very common and most of you would have faced it.
I have written a program in lua, say main.lua which on receiving key event should modify the coordinates and display the geometry figure.
This lua code calls reg.c, where it kind of registers.
Now in reg.c i have a function engine which receives the key pressed and passes it to the lua function responsible for key handling.
But by the time key event comes, lua code is done with the registration and exits, thus the call from engine() becomes illegal memory access leading to segmentation fault.
Also i suppose we can't have lua call hanging in reg function, and call engine function from somewhere else.
Then what should be the solution, please guide me through this.
#jacob: here is the prototype of what i am trying to achieve:
function key_handler() //this function will get the latest key pressed from some other function
{
draw.image();
draw.geometry();
...
...
while(1)
{
//draw Points until some condition goes wrong
}
}
Now, once entered into key_handler, while he is busy drawing the points unless and until the failing condition occurs, i am unable to receive key pressed till that time.
I hope this explanation is much simpler and have made my point, and will help others to understand the problem.
I am really sorry, but i am not good at expressing or making others understand.
One more thing, i ahve followed the C syntax to explain, however this is completely implemented in lua
Your code snippet is still largely non-informative (ideally one should be able to just run your code in a stock Lua interpreter and see your problem). If you're describing a Lua problem, use Lua code to describe it.
However I'm beginning to see where you want to go.
The thing you need to could do is have a coroutine that's called in your key handler, which passes an argument back to your handler:
function isContinue() --just to simulate whatever function you use getting keypresses.
-- in whatever framework you're using there will probably be a function key_pressed or the like.
print('Initialize checking function')
while true do
print('Continue looping?')
local ans = io.read():match('[yY]')
local action
if not ans then
print('Do what instead?')
action = io.read()
if action:match('kill') then -- abort keychecker.
break
end
end
coroutine.yield(ans,action)
end
print('finalizing isContinue')
return nil,'STOP' -- important to tell key_handler to quit too, else it'll be calling a dead coroutine.
end
function key_handler()
local coro = coroutine.create(isContinue)
local stat,cont,action
while true do
print'Draw point'
stat,cont,action = coroutine.resume(coro)
if not stat then
print('Coroutine errored:',cont)
elseif not cont then
print('isContinue interrupted keyhandler')
print("We'll "..action.." instead.")
break
end
end
print('finalizing key_handler')
end
key_handler()
-- type something containing y or Y to continue, all else aborts.
-- when aborting, you get asked what to do instead of continuing,
--- with "kill" being a special case.
This should be self explanatory. You should probably take a good look at Programming in Lua, chapter 9: Coroutines.
The big difficulty (well, if you're not accustomed to collaborative threading) is that a coroutine should yield itself: it's not the calling function that's in charge of returning control.
Hope this helps you.
I'm writing a program where the user must enter a 'yes' or 'no' value. The following is the code that will be executed when the message {createPatient,PatientName} is received.
{createPatient, PatientName} ->
Pid = spawn(patient,newPatient,[PatientName]),
register(PatientName,Pid),
io:format("*--- New Patient with name - ~w~n", [PatientName]),
Result = io:read("Yes/No> "),
{_,Input} = Result,
if(Input==yes) ->
io:format("OK")
end,
loop(PatientRecords, DoctorPatientLinks, DoctorsOnline, CurrentPatientRequests, WaitingOfflineDoctorRequests);
When executed ,the line "New Patient with name..." is displayed however the line Yes/No is not displayed and the program sort of crashes because if another message is sent, then the execution of that message will not occur. Is there a different way to solve this problem please?
There are a number of points I would like to make here:
The io:read/1 function reads a term, not just a line, so you have to terminate input with a '.' (like in the shell).
io:read/1 returns {ok,Term} or {error,Reason} or eof so you code should check for these values, for example with a case.
As #AlexeyRomanov mentioned, io:get_line/1 might be a better choice for input.
The if expression must handle all cases even the ones in which you don't want to do anything, otherwise you will get an error. This can be combined with the case testing the read value.
You spawn the function patient:newPatient/1 before you ask if the name is a new patient, this seems a little strange. What does the newpatient function do? Is it in anyway also doing io to the user which might be interfering with functions here?
The main problem seems to be work out what is being done where, and when.
This is very artificial problem. In erlang any communication is usually inter-process and exchanging strings wouldn't make any sense - you ask question in context of process A and you would like to post answer in context of process B (shell probably).
Anyways, consider asking question and waiting in receive block in order to get an answer.
When question pops out in shell, call a function which will send the answer to 'asking' process with your answer.
So:
io:format("*--- New Patient with name - ~w~n", [PatientName]),
receive
{answer, yes} -> do_something();
{answer, no} -> do_something()
end
The 'answering' function would look like that:
answer(PatientName, Answer) ->
PatientName ! {answer, Answer}.
And shell action:
$> *--- New Patient with name - User1036032
$> somemodule:answer('User1036032', yes).
It is possible to create some dialog with shell (even unix shell), but to be honest it is used so rare that I do not remember those I/O tricks with read and write. http://trapexit.com/ used to have cookbook with this stuff.
Use io:get_line("Yes/No> ") instead.
When using spock+geb you can assert that you are on expected page by assertion e.g.:
assert title == 'Sign In'
and you get a nice failure trace if assertion fails:
Condition not satisfied:
title == 'Sign In'
| |
Login false
5 differences (28% similarity)
(Lo)g(i--)n
(Si)g(n I)n
But if I try to use page object pattern e.g.:
class LoginPage extends GebPage {
static at = { title == 'Sign In' }
}
Trace is not very helping what's going wrong:
Condition not satisfied:
at(LoginPage)
|
false
Is there any way how to use page object pattern and get more descriptive failure trace ?
According to geb mailing list responses the current workaround is:
static at = { assert title == 'Sign In'; true }
Thanks to David & Luke.
Offhand, I'm not sure if I have an answer to your question. I believe I had a similar question at some point, but other issues became more important after time (such as the fact that WebDriver is a POS). You won't find Stackoverflow to be much use when it comes to new & emerging libraries, such as Geb.
Your best bet is to post a message on Geb's mailing list instead. You can find it here.
Luke Daley, the creator of Geb, usually responds to messages on a daily basis & is extremely helpful. The mailing list is quite useful, even though the number of members is small at this point.