paul.allton at uk.bnpparibas.com wrote: > I''m a big fan of automated UI testing (i.e. driving the UI from some robot API). I appreciate this > is potentially a whole new project, but does wxwidgets provide a method of clicking buttons, > typing into components ... if so, would it be technically possible to expose this in wxruby. I like automated UI testing too, but don''t know of a single solution for now. To exercise the API of a particular component you have written, you can create fast ''headless'' tests by creating a host app and frame, but not showing the frame. Take a look at tests/test_item_data.rb in the distribution for an example. But I guess you are also interested in testing a GUI as a whole. There are two routes you might consider: 1) Use the fact that wxruby creates native widgets and drive the GUI using something like AutoIt (http://www.autoitscript.com/autoit3/), using Ruby + Win32OLE as glue (http://wiki.rubygarden.org/Ruby/page/show/AutoIt_For_Windows). There are some options on OS X as well: http://groups-beta.google.com/group/comp.lang.ruby/browse_thread/thread/5423c75db1a53c2d?hl=en The disadvantages are these being single platform solutions. With some shallow experimentation, I also found AutoIt''s window handles a bit clumsy to use for testing. The only real advantage I can see is being able to record actions. 2) I think a better way would be to use the wxRuby API to simulate events directly. Event objects are instantiable like any other, and they can then be passed to the app objects for handling by using EvtHandler#process_event or #add_pending_event. A snippet that works for me (OS X, 0.0.38) f = Wx::Frame.new(nil, -1, ''test_app'') b = Wx::Button.new(f, -1, ''click'') evt_button(b.get_id) { | e | Kernel.raise ''I was clicked'' } # I got this 10003 id by calling get_event_type on a real button event test_event = Wx::CommandEvent.new(10003, b.get_id) # simulated event processsing - call the event handler above process_event(test_event) I would be interested in developing a neater API to this. The event type constants (eg 10003 for EVT_TYPE_BUTTON) may be exposed already somewhere in wxruby but I don''t know off hand. You might also take a look at an older post on this topic: http://rubyforge.org/pipermail/wxruby-users/2005-January/001091.html cheers alex
> test_event = Wx::CommandEvent.new(10003, b.get_id) > # simulated event processsing - call the event handler above > process_event(test_event) > > I would be interested in developing a neater API to this. The event type > constants (eg 10003 for EVT_TYPE_BUTTON) may be exposed already > somewhere in wxruby but I don''t know off hand. >Just came across them. You could rewrite the above as test_event = Wx::CommandEvent.new(Wx::EVT_COMMAND_BUTTON_CLICKED, b.get_id) You can find all the relevant constants for event types by doing Wx::constants.grep /^EVT_/ The syntax is a bit unwieldy, though event types constants are only needed for command events. This however covers many common UI interactions one might want to simulate, so I''d look to add a ''simulate'' API to wxSugar. I''m open to suggestions on what this should look like; maybe simulate(:click, my_button) alex
paul.allton at uk.bnpparibas.com
2006-Dec-20 16:00 UTC
[Wxruby-users] unit testing wxruby GUIs
>To exercise the API of a particular component you have written, you can >create fast ''headless'' tests by creating a host app and frame, but not >showing the frame. Take a look at tests/test_item_data.rb in the >distribution for an example.>But I guess you are also interested in testing a GUI as a whole. There >are two routes you might consider:Yup, I''m unfortunately at that stage where *unit* testing individual component/models, (while useful) is a minimum requirement. I''d not undertake any project without having acceptance tests for the UI.>1) Use the fact that wxruby creates native widgets and drive the GUI >using something like AutoIt (http://www.autoitscript.com/autoit3/), >using Ruby + Win32OLE as glue >(http://wiki.rubygarden.org/Ruby/page/show/AutoIt_For_Windows).>There are some options on OS X as well: >http://groups-beta.google.com/group/comp.lang.ruby/browse_thread/thread/5423c75db1a53c2d?hl=en>The disadvantages are these being single platform solutions. With some >shallow experimentation, I also found AutoIt''s window handles a bit >clumsy to use for testing. The only real advantage I can see is being >able to record actions.Agree, it''s gotta be cross platform ... I guess I was originally thinking that it would be something wxWidgets should provide. A simple robot built into the platform (like java''s Robot - http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Robot.html) that can be wrapped by whatever platform (wxruby, wxpython etc) or framework requires it. Maybe that''s a bit too much to ask. I did stumble over this: http://www.wefi.net/swWxGuiTesting/, which sounds promising - but unfortunately I can''t parse c/c++ so I''ve no ideas if its of any actual use.>2) I think a better way would be to use the wxRuby API to simulate >events directly. Event objects are instantiable like any other, and they >can then be passed to the app objects for handling by using >EvtHandler#process_event or #add_pending_event.>A snippet that works for me (OS X, 0.0.38)> f = Wx::Frame.new(nil, -1, ''test_app'') > b = Wx::Button.new(f, -1, ''click'') > evt_button(b.get_id) { | e | Kernel.raise ''I was clicked'' } > # I got this 10003 id by calling get_event_type on a real buttonevent> test_event = Wx::CommandEvent.new(10003, b.get_id) > # simulated event processsing - call the event handler above > process_event(test_event)Sounds neat, will give this a try.>I would be interested in developing a neater API to this. The event type >constants (eg 10003 for EVT_TYPE_BUTTON) may be exposed already >somewhere in wxruby but I don''t know off hand.>You might also take a look at an older post on this topic:>http://rubyforge.org/pipermail/wxruby-users/2005-January/001091.htmlAlso interesting. I''d actually go the other way, personally I want to see the UI up and running during acceptance tests. I want to be able to interact with it when it goes wrong. I also like the watir (http://wtr.rubyforge.org/) style, flashing of components so you can see stuff happening. This message and any attachments (the "message") is intended solely for the addressees and is confidential. If you receive this message in error, please delete it and immediately notify the sender. Any use not in accord with its purpose, any dissemination or disclosure, either whole or partial, is prohibited except formal approval. The internet can not guarantee the integrity of this message. BNP PARIBAS (and its subsidiaries) shall (will) not therefore be liable for the message if modified. ********************************************************************************************** BNP Paribas Private Bank London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Securities Services London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Fund Services UK Limited is authorised and regulated by the Financial Services Authority -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/wxruby-users/attachments/20061220/47ffa4f4/attachment.html
paul.allton at uk.bnpparibas.com
2006-Dec-20 18:47 UTC
[Wxruby-users] unit testing wxruby GUIs
> Just came across them. You could rewrite the above as> test_event = Wx::CommandEvent.new(Wx::EVT_COMMAND_BUTTON_CLICKED,b.get_id)> You can find all the relevant constants for event types by doing>Wx::constants.grep /^EVT_/>The syntax is a bit unwieldy, though event types constants are only >needed for command events. This however covers many common UI >interactions one might want to simulate, so I''d look to add a ''simulate'' >API to wxSugar. I''m open to suggestions on what this should look like;maybe> simulate(:click, my_button)That looks pretty neat. I think where possible, if the events can be generated by the component rather than having to be hand-crafted then that might save a load of work. Certainly for Button it looks like you''d have to create the CommandEvent, but for example; TextCtrl seems to generate an evt_text whenever the value is set. In terms of API, I''m not too fussy what the low level API looks like, whatever works for you/is simple to implement. There are many ways to do this stuff, I''ve used a few API''s: java.awt.Robot, watir and jemmy ( http://jemmy.netbeans.org/samples.html), they all seem to work pretty well, but IMO suffer from too much complexity, so I usually end up building a higher level API anyway. This message and any attachments (the "message") is intended solely for the addressees and is confidential. If you receive this message in error, please delete it and immediately notify the sender. Any use not in accord with its purpose, any dissemination or disclosure, either whole or partial, is prohibited except formal approval. The internet can not guarantee the integrity of this message. BNP PARIBAS (and its subsidiaries) shall (will) not therefore be liable for the message if modified. ********************************************************************************************** BNP Paribas Private Bank London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Securities Services London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Fund Services UK Limited is authorised and regulated by the Financial Services Authority -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/wxruby-users/attachments/20061220/50dbc8e2/attachment.html
paul.allton at uk.bnpparibas.com
2006-Dec-20 19:02 UTC
[Wxruby-users] unit testing wxruby GUIs
I did a quick spike of naming some components, finding them and performing some simple actions, based on your earlier example. Button clicking and text entering seems to be okay, but I couldn''t get selecting from a Choice to work. Out of interest, is there a difference between component.command(event) and evt_handler.process_event(event)? The documentation for the former suggests that its meant to emulate the user. # the ui FOO = ''foo_frame'' BAR = ''bar_button'' BAZ = ''baz_text_ctrl'' THINGS = ''things_choice'' f = Frame.new(nil, -1, ''test_app''); f.name = FOO b = Button.new(f, -1, ''click''); b.name = BAR t = TextCtrl.new(f); t.name = BAZ c = Choice.new(f); [''a'', ''b'', ''c''].each {|n| c.append(n) }; c.name = THINGS # prove the automation works f.evt_button(b.get_id) {|e| puts ''I was clicked'' } f.evt_text(t.get_id) {|e| puts ''my text changed'' } f.evt_choice(c.get_id) {|e| puts "my selection changed: #{c.selection}" } # do some stuff click(BAR) type(''wibble'', into(BAZ)) select(''b'', from(THINGS)) # a bucket full of sugar def find_component(name) component = Window.find_window_by_name(name) Kernel.raise "cannot find component with name: #{name}" if component.nil? component end def into(name) find_component(name) end def from(name) find_component(name) end def click(name) component = find_component(name) component.command(CommandEvent.new(EVT_COMMAND_BUTTON_CLICKED, component.get_id)) end def type(text, component) #should probably enter 1 char at a time to ensure all events fired component.value = text end def select(value, component) event = CommandEvent.new(EVT_COMMAND_CHOICE_SELECTED, component.get_id) event.string = value component.selection = component.find_string(value) component.command(event) end This message and any attachments (the "message") is intended solely for the addressees and is confidential. If you receive this message in error, please delete it and immediately notify the sender. Any use not in accord with its purpose, any dissemination or disclosure, either whole or partial, is prohibited except formal approval. The internet can not guarantee the integrity of this message. BNP PARIBAS (and its subsidiaries) shall (will) not therefore be liable for the message if modified. ********************************************************************************************** BNP Paribas Private Bank London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Securities Services London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Fund Services UK Limited is authorised and regulated by the Financial Services Authority -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/wxruby-users/attachments/20061220/ba148deb/attachment-0001.html
paul.allton at uk.bnpparibas.com wrote:> I did a quick spike of naming some components, finding them and > performing some simple actions, based on your earlier example.Thank you, very interesting; I like where you''re going with this. Are you looking to integrate this with test/unit in the end? Or automating and watching what happens?> Button clicking and text entering seems to be okay, but I couldn''t get > selecting from a Choice to work.See below.> Out of interest, is there a difference between > component.command(event) and evt_handler.process_event(event)? The > documentation for the former suggests that its meant to emulate the user.I didn''t know about the Wx::Control#command method. I think it, not process_event, is the correct one to use so that the event is routed to the right handler as if a user had performed the action. Some comments on your code:> # the ui > FOO = ''foo_frame''It would be nice not to have to explicitly name every widget you might want to automate. I want to fix the Wx::Window#get_children method soon, which will allow wxruby programs to traverse a widget hierarchy and find un-named widgets. Maybe something like: a_button = a_frame.find(Button) { | b | b.label == ''click'' }> c = Choice.new(f); [''a'', ''b'', ''c''].each {|n| c.append(n) }; c.name = > THINGSwith wxsugar, you can just do: c = Choice.new(f, :choices => [''a'', ''b'', ''c'']) or even terser: c = Choice.new(f, :choices => %w|a b c|)> # do some stuff > click(BAR) > type(''wibble'', into(BAZ)) > select(''b'', from(THINGS))Cool - this kind of (overused word) DSL works nicely for an automation/acceptance testing approach.> def select(value, component) > event = CommandEvent.new(EVT_COMMAND_CHOICE_SELECTED, component.get_id) > event.string = value > component.selection = component.find_string(value)Instead of actually setting the selection of the choice widget, we want to say what selection is being set in the simulated event. The wxWidgets docs aren''t helpful, but: event.int = component.find_string(value) # (or in non-sugar wxRuby) event.set_int(component.find_string(value)) seems to be the correct method to call and works for me. cheers alex
paul.allton at uk.bnpparibas.com
2006-Dec-21 18:50 UTC
[Wxruby-users] unit testing wxruby GUIs
>Thank you, very interesting; I like where you''re going with this. Are >you looking to integrate this with test/unit in the end? Or automating >and watching what happens?Both. I''d prefer to keep the gui driving bit separate from the testing bit, the driver is then useful in its own right. So, I wouldn''t expect to see any assertion methods on the robot, but obviously the standard text/unit assertions can be used within the test, i.e: class SpikeTest < Test::Unit::TestCase def test_something click(BAR) type(''wibble'', into(BAZ)) select(''b'', from(THINGS)) assert_equal(''b'', selection(THINGS).selected_value) end end ### more support sugar def selection(name) Selection.new(name) end class Selection def initialize(name) @name = name end def selected_value find_component(@name).string_selection end end ### amended select method following your advice def select(value, component) event = CommandEvent.new(EVT_COMMAND_CHOICE_SELECTED, component.get_id) event.int = component.find_string(value) component.command(event) end>It would be nice not to have to explicitly name every widget you might >want to automate. I want to fix the Wx::Window#get_children method soon, >which will allow wxruby programs to traverse a widget hierarchy and find >un-named widgets. Maybe something like:>a_button = a_frame.find(Button) { | b | b.label == ''click'' }I''m actually quite keen on components being found by name as it avoids complication and I don''t see naming components too much of a burden. In other frameworks I''ve used its been very easy to get into a mess with finding by index/xpath expressions etc - these tend to be very brittle. That said, the ability to find by label is definitely useful/reasonable so I''d go for the default find_component to use name/label whichever it finds first maybe. Incidentally, it would be nice if [:name => ''foo''] was a sugared constructor arg :) (slightly off topic ... wx-sugar is great ... but could we have some more examples please .. maybe take some of the bigdemo samples and sugar them up?)>Cool - this kind of (overused word) DSL works nicely for an >automation/acceptance testing approach.FWIW, I''ve been involved with evolving a testing API in java which looks virtually identical to the above ruby code and seems to work fairly well for testing both rich client and web UI''s (using the same language). We''ve also found its possible to build an even higher level API which makes the above look, er ... low level ... but that may not be to everyone''s taste. It really does then become domain specific (but I''d prefer not to use that term ;)).>Instead of actually setting the selection of the choice widget, we want >to say what selection is being set in the simulated event. The wxWidgets >docs aren''t helpful, but:>event.int = component.find_string(value) ># (or in non-sugar wxRuby) >event.set_int(component.find_string(value))Thanks for that. Although it fires the event okay, the resulting selection doesn''t change. The test above actually shows the problem .. heres the output: Loaded suite spike Started I was clicked my text changed my selection changed: 0 F Finished in 0.078 seconds. 1) Failure: test_something(SpikeTest) [spike.rb:90]: <"b"> expected but was <"">. For some reason the selection is always 0 and the text is "", any ideas why that might be? At this stage it would be useful to be able to visually show the frame and see what''s actually going on, ''f.show'' doesn''t seem to do anything though, does it need to be wrapped in an app to be shown? p. This message and any attachments (the "message") is intended solely for the addressees and is confidential. If you receive this message in error, please delete it and immediately notify the sender. Any use not in accord with its purpose, any dissemination or disclosure, either whole or partial, is prohibited except formal approval. The internet can not guarantee the integrity of this message. BNP PARIBAS (and its subsidiaries) shall (will) not therefore be liable for the message if modified. ********************************************************************************************** BNP Paribas Private Bank London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Securities Services London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Fund Services UK Limited is authorised and regulated by the Financial Services Authority -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/wxruby-users/attachments/20061221/16edfbde/attachment.html
paul.allton at uk.bnpparibas.com wrote:> >a_button = a_frame.find(Button) { | b | b.label == ''click'' } > > I''m actually quite keen on components being found by name as it avoids > complication and I don''t see naming components too much of a burden.Good, well if it''s not a problem, it''s not a problem...> In other frameworks I''ve used its been very easy to get into a mess > with finding by index/xpath expressions etc - these tend to be very > brittle.I agree that''s fragile. I think a find_window + block specifying a match is less so, and also more general and ruby-ish than find_window_by_label. But find_window_by_label etc won''t be going away - it''s part of the core API.> Incidentally, it would be nice if [:name => ''foo''] was a sugared > constructor arg :)Yep. It will be soon. There was an unrelated wxruby2 obstacle to this for control classes, but should be fixed in next release.> (slightly off topic ... wx-sugar is great ... but could we have some > more examples please .. maybe take some of the bigdemo samples and > sugar them up?)Yep, the sugar sample is lame, but it''s lower priority than nailing the last bits of wxruby2. There are lots of sugar real-life samples in Weft QDA: http://rubyforge.org/viewvc/trunk/weft-qda/lib/weft/wxgui/?root=weft-qda It''s where most of wxSugar germinated. It''s a decent sized app, which means it has quite a lot of ruby dependencies to install to run. You can browse the GUI code online - the ''inspectors'' might be of interest: http://rubyforge.org/viewvc/trunk/weft-qda/lib/weft/wxgui/?root=weft-qda> FWIW, I''ve been involved with evolving a testing API in java which > looks virtually identical to the above ruby code and seems to work > fairly well for testing both rich client and web UI''s (using the same > language).I''ve got no experience with Java, and your knowledge of GUI testing with a well-established language has given us excellent insight on this topic. Thanks.> >event.int = component.find_string(value) > > Although it fires the event okay, the resulting selection doesn''t > change. The test above actually shows the problem ... heres the output:Hmm - I''ve just run it again and it definitely works for me (OS X 10.3)> For some reason the selection is always 0 and the text is "", any > ideas why that might be?See below.> At this stage it would be useful to be able to visually show the frame > and see what''s actually going on, ''f.show'' doesn''t seem to do anything > though, does it need to be wrapped in an app to be shown?Don''t ever instantiate or show a Window/Frame etc outside of an App.main_loop. It might sort-of work on some platforms, but on others it will fail or even segfault. I suspect that the problem you''re seeing with the simulated Choice event might be because it''s outside main_loop, and so the event routing and handling isn''t set up properly. Apologies - this is a documentation bug in wxruby2. We need to ''translate'' and move some of the topic overviews and tutorials from wxWidgets docs and the wxruby wiki into the core wxruby2 docs. Eg: http://wxruby.rubyforge.org/wiki/wiki.pl?Getting_Started cheers alex
paul.allton at uk.bnpparibas.com
2007-Jan-03 10:04 UTC
[Wxruby-users] Simple wxRuby Doc Browser
Hi, The new wxruby docs are really great :) I wanted a slightly easier way of finding available methods. Below is a quick hack of a documentation browser (apologies its inline, I wasn''t sure if this list handled attachments). I''m already finding it quite useful, but there''s a few issues to sort out: - On loading the app, I call @narrower.set_focus so that you can start typing to narrow the list of methods. This works fine on windows, but on OS X it will not focus until you physically click into the TextCtrl. Is this a bug, or am doing something dense? - On selecting a method in the list the HtmlWindow redirects to the associated page. This works fine for standard links, but for anchors it always results in the popup box ''Ruby Warning'' - ''HTML anchor xxx does not exist.'', on both windows and OS X. Again, is this user error or a wxruby issue? (Note: to run it you''ll need to change the line ''Dir.chdir(''C:\dev\jwx2doc\doc\html'')'' to the directory containing the wxruby html documentation files. Finally, when you run it the (very lame) html parsing spits out a warning for each file that doesn''t include any methods, which might help identify classes where the original documentation generation was a bit iffy. Cheers, Paul ################################################### require ''rubygems'' require ''wx'' require ''wx_sugar/all'' include Wx class WxDocFrame < Frame def initialize(*args) super @splitter = add(SplitterWindow[:style => SP_LIVE_UPDATE]) p1 = @splitter.add(Panel) {|p1| p1.arrange_vertically(:padding => 1) { @narrower = p1.add(TextCtrl, :minsize => true) @methods = p1.add(ListBox, :proportion => 1) } } p2 = @splitter.add(Panel) {|p2| p2.arrange_vertically { @detail = p2.add(HtmlWindow, :proportion => 1) } } init_model create_status_bar(1) listen(:text, @narrower, :on_narrower_change) listen(:listbox, @methods, :on_method_selection) @splitter.minimum_pane_size = 10 @splitter.split_vertically(p1, p2, 350) @splitter.set_sash_gravity(0.5) @narrower.set_focus @narrower.value = '''' end private def init_model @model = {} Dir.glob(''*.html'') {|file| IO.readlines(file).join.scan(/^<li><a href="(.*?)">(.*?)<\/a><\/li>$/) {|url, method| @model[method] = [file, url] } } set_methods(@model.keys.sort) end def on_narrower_change(e) value = @narrower.value.downcase set_methods(@model.keys.sort.select{|m| m.downcase.include?(value) }) end def on_method_selection item = @model[@methods.string_selection] @detail.load_page(item[0] + item[1]) end def set_methods(methods) @methods.set(methods) self.status_text = "#{methods.size} matching methods" end end class WxDocApp < App def on_init WxDocFrame.new(nil, :title => "wxRuby Documentation", :size => [1024, 768]).show end end #temp for latest windows gem GC.disable Dir.chdir(''C:\dev\wx2doc\doc\html'') WxDocApp.new.main_loop This message and any attachments (the "message") is intended solely for the addressees and is confidential. If you receive this message in error, please delete it and immediately notify the sender. Any use not in accord with its purpose, any dissemination or disclosure, either whole or partial, is prohibited except formal approval. The internet can not guarantee the integrity of this message. BNP PARIBAS (and its subsidiaries) shall (will) not therefore be liable for the message if modified. ********************************************************************************************** BNP Paribas Private Bank London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Securities Services London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Fund Services UK Limited is authorised and regulated by the Financial Services Authority -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/wxruby-users/attachments/20070103/6a8bbe46/attachment.html
Hi paul.allton at uk.bnpparibas.com wrote:> I wanted a slightly easier way of finding available methods. Below is > a quick hack of a documentation browser (apologies its inline, I > wasn''t sure if this list handled attachments).Looks good; it could be the nugget of a nice demo sample. This list does accept attachments of reasonable size - scripts and patches are normally fine.> - On loading the app, I call @narrower.set_focus so that you can start > typing to narrow the list of methods. This works fine on windows, but > on OS X it will not focus until you physically click into the > TextCtrl. Is this a bug, or am doing something dense?I was wondering the same thing this weekend, where set_focus wasn''t working in a TextCtrl within a MiniFrame on OS X. I''ll file a bug for it - will need to check whether it''s a OS X thing or a wxruby error.> - On selecting a method in the list the HtmlWindow redirects to the > associated page. This works fine for standard links, but for anchors > it always results in the popup box ''Ruby Warning'' - ''HTML anchor xxx > does not exist.'', on both windows and OS X.The wxruby docs use modern-style HTML anchors (<p id="foo">) not old style (<a name="foo"></a><p>...). Unfortunately the generic HTML widget only knows about the latter. This will be hard to fix , but a quicker route is to old-ify the documentation: docs_dir = ''D:\path\to\wxruby-docs-0.0.38\doc\html'' Dir.glob(File.join(docs_dir, "*.html") ) do | old | content = File.read(old) content.gsub!(/<(\w+) id="(\w+)"/, %q|<a name="\2"></a><\1 id="\2"|) File.open(old, ''w'') { | f | f.write(content) } end cheers alex
paul.allton at uk.bnpparibas.com
2007-Jan-05 09:25 UTC
[Wxruby-users] Simple wxRuby Doc Browser
>The wxruby docs use modern-style HTML anchors (<p id="foo">) not old >style (<a name="foo"></a><p>...). Unfortunately the generic HTML widget >only knows about the latter. This will be hard to fix , but a quicker >route is to old-ify the documentation:>docs_dir = ''D:\path\to\wxruby-docs-0.0.38\doc\html'' >Dir.glob(File.join(docs_dir, "*.html") ) do | old | > content = File.read(old) > content.gsub!(/<(\w+) id="(\w+)"/, %q|<a name="\2"></a><\1 id="\2"|) > File.open(old, ''w'') { | f | f.write(content) } >endNice one, thanks Alex. Are there any plans to include the docs in the gem install rather than a seperate download? This message and any attachments (the "message") is intended solely for the addressees and is confidential. If you receive this message in error, please delete it and immediately notify the sender. Any use not in accord with its purpose, any dissemination or disclosure, either whole or partial, is prohibited except formal approval. The internet can not guarantee the integrity of this message. BNP PARIBAS (and its subsidiaries) shall (will) not therefore be liable for the message if modified. ********************************************************************************************** BNP Paribas Private Bank London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Securities Services London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Fund Services UK Limited is authorised and regulated by the Financial Services Authority -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/wxruby-users/attachments/20070105/43f0b010/attachment.html
paul.allton at uk.bnpparibas.com
2007-Jan-05 14:18 UTC
[Wxruby-users] wxRuby GUI driver ... programmatically open and close an app
Hi, As part of the ongoing spike to build an API for driving wxruby UI''s (as discussed in previous threads) - I''m wondering what the best way is to programmatically open and close an app. Below is sample test using what have so far... but there are some issues I can''t seem to get around: (1) In the test setup I''m launching the app, but I have to jump through some hoops to stop the application from blocking (especially on windows). It sort of works if I spawn a thread ... and (this bit really sucks) add a timer to the app that yields every now and then .. like so: @timer = Timer.new(self, -1) @timer.start(10) evt_timer(@timer.id) {|e| self.yield } This seems rather nasty .. is there a better way? Also, whilst this is very snappy on OSX, it seems v. slow on windows. (2) In teardown, I''m trying to stop the app, which seems to work fine (i.e. it disappears). The problem is that if I add a second test case, the second time it enters setup and tries to start the app.main_loop it blows up. On windows with a Segmentation fault, on OS X with a bus error. Clearly, I''m not doing this quite right, any ideas? p. ################################################################# (note: this won''t run on its own, its just for info) class CollectTest < Test::Unit::TestCase def setup Thread.critical = false app_thread = Thread.new { @app = GtdApp.new @app.main_loop } app_thread.priority = -1 sleep 1 Thread.critical = true end def test_something type(''wibble'', in_(GtdFrame::COLLECT_CONTENT)) click(GtdFrame::COLLECT_SAVE) assert_equal('''', text(component(in_(GtdFrame::COLLECT_CONTENT)))) selection(in_(GtdFrame::NOTEBOOK)).choose(GtdFrame::PROCESS_PAGE) assert_equal(GtdFrame::PROCESS_PAGE, selection(in_(GtdFrame::NOTEBOOK)).selected_value) assert_equal(''wibble'', text(component(in_(GtdFrame::PROCESS_CONTENT)))) end def teardown @app.top_window.destroy @app.exit_main_loop @app = nil GC.start end end This message and any attachments (the "message") is intended solely for the addressees and is confidential. If you receive this message in error, please delete it and immediately notify the sender. Any use not in accord with its purpose, any dissemination or disclosure, either whole or partial, is prohibited except formal approval. The internet can not guarantee the integrity of this message. BNP PARIBAS (and its subsidiaries) shall (will) not therefore be liable for the message if modified. ********************************************************************************************** BNP Paribas Private Bank London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Securities Services London Branch is authorised by CECEI & AMF and is regulated by the Financial Services Authority for the conduct of its investment business in the United Kingdom. BNP Paribas Fund Services UK Limited is authorised and regulated by the Financial Services Authority -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/wxruby-users/attachments/20070105/6e04707f/attachment.html
> Are there any plans to include the docs in the gem install rather than > a seperate download?There''s no technical reason why not; it could be changed. We went for separate download to allow people to unpack the docs somewhere that suited them, rather than a directory deep inside ruby/lib/gem/... a thought on DocBrowser - you might take a look at HtmlHelpController - it would need a few extra files to be generated, but offers keyword search and hierarchical indexes etc for html docs alex
Alex Fenton
2007-Jan-08 09:19 UTC
[Wxruby-users] wxRuby GUI driver ... programmatically open and close an app
paul.allton at uk.bnpparibas.com wrote:> (1) In the test setup I''m launching the app, but I have to jump > through some hoops to stop the application from blocking (especially > on windows).Do you mean that once you''ve entered main_loop no further code is executed?> It sort of works if I spawn a thread ... and (this bit really sucks) > add a timer to the app that yields every now and then .....> is there a better way?If you want to execute arbitrary outside code in the context of a running app, you can have the constructor or main_loop accept a block, store it and yield to that at the end of on_init. You could use a module to isolate this from the code under test (adapted from real code but untested) module TestingApp def run_on_init(&block) @run_on_init = block end def on_init(*args) super if @run_on_init @run_on_init.call(self) end true end end app = MyApp.new app.extend(TestingApp) app.run_on_init { # testing code here } app.main_loop> (2) In teardown, I''m trying to stop the app, which seems to work fine > (i.e. it disappears). The problem is that if I add a second test > case, the second time it enters setup and tries to start the > app.main_loop it blows up.This won''t work - stick to one instance of Wx::App per script. I asked about this on the wx list recently, and seems no easy way for the wrapper to get round this at the moment. cheers alex