attach_file with cucumber+capybara+selenium on Windows

Posted on

Yesterday I was working with some scenarios having to do with file upload, and I thought they were failing because of something I was doing in the code, but they were not failing for my colleague on a mac (you don’t have to tell me what the obvious solution to this is, I know).

When I used the attach_file method in capybara with the selenium driver, the file input field would get filled in, but nothing would get submitted– there just wouldn’t be anything for the file parameter in the logs. What’s weird is that file upload worked just fine if I did it manually.

I checked out the capybara code and ran the gem’s specs on my machine, and sure enough, the specs testing attach_file with selenium failed for me as well.

The issue seems to be with the direction of the slashes in the paths. When I used attach_file, the paths would look like:

C:/Ruby/capybara/lib/capybara/spec/fixtures/test_file.txt

While doing it manually through the browser gave me paths that looked like:

C:\Ruby\capybara\lib\capybara\spec\fixtures\test_file.txt

So if I changed my step definition in features/step_definitions/web_steps.rb for attaching a file to be:

When /^(?:|I )attach the file "([^\"]*)" to "([^\"]*)"(?: within "([^\"]*)")?$/ do |filename, field, selector|
  with_scope(selector) do
    filepath = File.join(RAILS_ROOT, 'features', 'upload_files', filename)
    if filepath.match(/^C:\//)
      filepath.gsub!(/\//, "\\")
    end
    attach_file(field, filepath)
  end
end

then my cucumber scenarios worked as expected.

I’ve posted to the capybara mailing list to see if anyone knows where this problem is originating (and where a patch should be made) and if this is a good solution or if it’s just getting around a more fundamental problem. Anyone reading this have any ideas?

Another day in the life of a Windows+Ruby dev

Posted on

So today I decided to try to fix issue 358 of cucumber. I’m not even to the point of reproducing the bug yet. sigh

So I checked out the cucumber source and tried to install it, at which point rake decided to stop working since cucumber has rake as a development dependency and trying to install rake on windows with 1.9.2 breaks rake. Luckily, there was a quick workaround for that (deleting rake.gemspec).

Then, since I was trying to do rake install\_gem (which is the documented way to install cucumber from source and appears to be a Bundler task), I ran into the bug described in this ruby-bundler google group post wherein that task would quit with error message “Unable to determine name from existing gemspec. Use :name => ‘gemname’ in #install_tasks to manually set it.” (and no, following the instructions in the error message doesn’t help). Arve in that post seems to have a patch to bundler to fix it, which I tried applying, but it didn’t fix it for me.

So then I just decided to try rake -T in cucumber, and there are tasks build and install that work and also seem to be Bundler tasks, even though install_gem doesn’t work.

I think I can finally try reproducing that cucumber bug now, and I’ll put looking into the bundler issue on my list for another day.

At least I’m learning a lot!

NFL Playoffs Infographic Usability Fail

Posted on

I’m going to make my first post on this here blog about user experience and more specifically the usability of the graphics discussing the NFL playoffs. User experience and watching American football are other passions of mine in addition to programming in Ruby. I feel like its appropriate to expand the scope of my blog to include usability but that regularly including football would be scope creep ;)

Infographic on CBS during the Steelers-Browns game

My beef today is with the infographics that use x, y and z when discussing the NFL playoff picture. The use of these arbitrary letters is oddly ubiquitous throughout various media outlets’ coverage of who has made the playoffs in which method, and using the letters makes it more difficult to understand the situation. Following my reasons for why this is so confusing are some suggestions as to how this information could be presented more clearly.

Confusion

I did some research into the reasons behind using these letters and all I could find was this question and its answer that seemed to be confusing the letters I’m interested in with the ones given to various receivers. I also asked Dave, the person with the most sports trivia knowledge that I know, why these letters are used, and he said he had no idea. Please let me know in a comment if there is a reason I’m unaware of.

One potential reason is that these are just meant as footnotes. However, if that is the case, why wouldn’t all these networks just use an existing, well known standard for footnotes such as superscript numbers, numbers in brackets, asterisks or daggers?

That these independent entities are not using an existing footnote standard and are instead using the same letters x, y and z might indicate that there is a universal meaning. If I spent time memorizing the meaning of these letters in this context, then I would know what the letters mean across all the networks and I wouldn’t have to read the footnotes.

However, there is NO universal reason for the use of these letters because the letters don’t have the same meaning across networks! Some networks are even augmenting this “standard” with an actually standard asterisk, used in the same manner as the letters (why not add another letter??)

Source x y z *
NFL.com Playoff Berth Wild Card Division Division and Home Field
ESPN Playoff Berth Wild Card Division Division and Home Field
CBS Sports [1] Playoff Berth Division First-round Bye Home Field
NBC Sports Playoff Berth Division Conference
Fox Sports Division and Home Field Division Playoff Berth

[1] - also note that the meanings of the letters used on CBS Sports’ website differ from the meanings used in the graphic above that I saw used on TV by CBS!! [2]

[2] - see what I did there with those nice, standard footnotes?

So partly because the letters have no inherent meaning and partly because the letters have different meanings from different sources, when trying to figure out the information a graphic like this is telling me, I end up starting to scan from the top, then jumping to the bottom, then back up to where I was reading, then to the next line, then back down to the bottom, etc. I inevitably forget what a letter means even if I have already seen it, and once the graphic is removed from the screen I still feel like I have no idea who is definitely in or out of the playoffs. Unless you are deliberately trying to make it confusing, leaving the user devoid of the message you say you are trying to send is infographic fail.

Improvements

Whenever trying to improve the usability of software, the User Experience team at the company where I work will usually identify the target user and then pop the “why” stack to discover the target user’s goals. I have found this to be quite an effective way to get started, so let’s do that here.

For once, I am the user– and I would say that I am a consistent but casual fan. I enjoy watching the games and I do so on a regular basis, and because I watch on a regular basis I am familiar with most of the terms and events of football. I’m not a superfan who knows absolutely everything about the game, nor am I a purely social fan who only watches games incidentally and who likely knows less about the game in general. I’m also not an announcer, coach, player, or associated with the NFL in any official capacity (each of those could be potential users of this graphic as well).

I also discussed this topic with my partner-in-crime Jake, who I would put in the same category of casual-consistent, which doubles my sample size of users.

I’d also posit that our type of fan should be the target type for the networks. I would bet that most fans are casual-consistent (definitely more than superfans). Also, we should be the most valuable to marketers due to the consistent part (superfans are consuming everything about football from everyone already, so you’re not going to gain market share by wooing them) and that you’d want to grow this type of fan by converting the social fans (although not alienate or annoy the superfans). More tenuously, I’d hypothesize that one way you would convert the social fans would be to make it easier to understand, follow, and thus enjoy the game, and clearer infographics could be one part of that strategy.

Therefore, we can assume that the networks would most like to be useful to fans like Jake and me, with secondary goals of being understandable to social fans and not talk down to superfans. As one of those users, I personally am looking to know who is definitely or possibly:

  1. In the playoffs
  2. Has a first-round bye
  3. Has home field advantage

Jake also has convinced me that the teams’ records should be on there, so that you have an indicator of roughly how good each team is in comparison to the other teams and so that you wouldn’t have to remember that from a separate infographic.

Why do we want to know these things? So I know if the team I am rooting is going to be playing in the post season or not, first of all, and how likely or unlikely that is. Then if I’m still interested (likely if my team isn’t definitely out), I’d like to know which teams are likely going to have which advantages (first-round bye and home field advantage) and what the matchups are going to be like (from the teams’ records). Why do I want to know that? To be able to talk to other fans about the situation, to know whether I should be vicariously nervous or excited or disappointed for the team I’m following. Why? Because I’m a consistent fan and I’m planning on watching next week (and I’m going to stop asking “why” there).

So let’s take another look at the CBS TV infographic– what could we take out that doesn’t serve the user goals?

Infographic on CBS during the Steelers-Browns game

I don’t care about division leader vs wild card vs “in the hunt”– I care about who is definitely in the playoffs and who only might be in the playoffs. I also don’t really care about how a team is getting to the playoffs (i.e. winning their division vs wild card)– I care if they definitely or possibly have the advantages of a first-round bye or home field.

Here’s my first attempt at a reorg:

Image lost in blog migration. Might be back someday.

I think this is an improvement as it gets rid of the footnotes (thus saving space and mental effort) and clearly shows who (at that point in the day) is definitely in the playoffs and who might be in the playoffs. I’m not even entirely sure if I got the home field advantage column right since the current information is so muddled, but I believe the division winners get home field advantage over the wild cards in the first round, so the division winners have “home” in their column (and whichever of indianapolis/jacksonville makes it in will get the home field advantage).

Thus you don’t HAVE to understand division winner vs wild card to understand who is in and who is out… which may actually be a disadvantage. An alternate layout I considered was having “slots” for the 4 division winners and 2 wild card. This layout would have had PIT/BAL in the AFC North divisional slot and BAL/PIT in the first wildcard slot when that was up in the air, and would have IND/JAX in the AFC south divisional slot. Then the BYE and HOME columns would have set values for each slot (with my current understanding of the playoff system and how one denotes “home field advantage”).

What do you think? Feel free to link to an alternate mockup if you have suggestions and I’d be happy to add them to this post.

Entitled vs. Elitist

Posted on

There’s a thread on reddit that asks “What is the biggest current problem in the Ruby community?” that I found to be very interesting. Among comments about performance, documentation, scientific and math libraries and an IDE was a bit of a flamewar about developing in ruby on windows.

The basic sides were “Windows programmers feel that they are entitled to having everything working on their system” and “The Ruby community is elitist”. I see the point to both sides. Yes, it sucks to develop on Windows and developers who work on gems in their spare time aren’t able to test in every single environment… but at the same time, there are a lot of crappy things that happen when trying to run Ruby code on Windows and no, sometimes switching to a different OS is really not an option.

I hope that as a developer on Windows who does want to help improve Ruby’s Windows support as well as be part of the “Ruby community” I’m not seen as feeling “entitled”.

Can’t we just all get along?

Top 5 reasons I develop in Ruby on Windows

Posted on

Here’s the post that Andrew has been waiting for: why I continue to try to develop Ruby in Windows rather than give up and switch to a Mac. Here, in order from least compelling at #5:

  1. I'm more comfortable with Windows. I know where I need to go to change settings, I'm used to the mental models. Often I find what happens in OSX doesn't line up with my expectations and I get confused. This one is least compelling because I learn quickly; I know I'd get used to a Mac if I used one more than I do now.
  2. I'm stubborn. Every time someone says "why don't you just use a Mac?" a part of me wants to stay on Windows just because they're trying to convince me not to.
  3. I like a challenge. Similar but distinct from my stubbornness, every time someone says that developing in Ruby on Windows is hard, I want to see if I can do it.
  4. The Ruby community doesn't seem interested in supporting Windows, in part because there aren't very many people trying to use Ruby on Windows. I'm trying to stand up and be counted as a Windows Ruby developer (and starting to try to fix bugs where I can) so that people who would like to get into Ruby but only have access to a Windows machine (or work in a Windows shop) are not just dismissed by the community and told to go buy different hardware (or use a VM) if they want to do Ruby. I think the community is doing itself a disservice by alienating people in this way (and I know that's debatable).
  5. My company's software (which includes a Rails app) is deployed on Windows (as well as Linux) and I'm the last person on my team developing in Windows on a daily basis. I feel like I need to be catching compatibility issues as early as possible and have a Windows environment at the ready for debugging any Windows-specific issues that arise. My company has been (and continues to be) sub-par at supporting Windows, and a good deal of our customers use our Windows version. This reason is most compelling because if I was working in Ruby or Rails somewhere that wasn't deploying on Windows, I would probably have a Mac as my primary work machine.

There you have it. Go ahead and try to argue with my reasons, but watch out for #4, that one might get in your way ;)

Bundler seems to be helping to prevent name conflicts

Posted on

So I’m not totally sure because I’m (obviously) not all that familiar with bundler, but it seems that if I have done a bundle install with a Gemfile where cucumber (and thus term-ansicolor) is included, “rails generate model Term” fails and says:

The name 'Term' is either already used in your application or reserved by Ruby on Rails. Please choose an alternative and run this generator again.

I’m assuming this has to do with the stuff bundler does to make sure there aren’t gem conflicts? I’m not sure how to look up if this is something bundler is doing…

Bu I did some experimentation– if I remove cucumber from the Gemfile, rails generate lets me create a model named Term just fine. Checking with a rails 2.3.8 app that doesn’t use bundler but in an environment where cucumber is installed DOES let you generate a model named Term– I checked that just to be sure I wasn’t imagining the bug I saw.

So you can still hit the bug if you create your model called Term, then add cucumber to your Gemfile, then run bundle install, then run rake cucumber.

This is definitely an improvement– I mostly wanted to fix this bug for people who, like me, were starting out not knowing much but knowing that they wanted to use cucumber and try and do BDD in the “right” way advocated by The RSpec Book, etc. and just happened to want to name their model Term. As long as they install Cucumber first, they should get a nice error message that tells them up front that they have to use a different model name, rather than a cryptic error later.

Now I have to decide if the bug is still worth me fixing… hmm.

Learning Bundler

Posted on

So after I figured out how to fix the cross-thread violations due to the json gem, and the other problems I ran into, I reproduced the bug I was actually attempting to fix. Then I checked out cucumber, changed my Gemfile to use my dev version of cucumber, did a bundle install and started poking around in the code while that finished. I noticed that the newest version of cucumber now uses ANSICON to do colors on windows– I’m not yet sure how that affects the bug I’m trying to fix that has to do with term-ansicolor.

One of the reasons I’m not yet sure is that, when I tried to reproduce the bug I’m trying to fix again once bundle install was done, the cross-thread violation was back! Since I didn’t specify what json gem I wanted at all in my Gemfile, cucumber pulled in the bad version of the json gem again.

I also learned that I needed to put my json specification:
  gem 'json', '=1.4.6', :platforms => [:ruby]
BEFORE my cucumber specification, in order to be sure that cucumber didn't dictate the version of json to be used.

Nevermind, it seems to be randomly choosing whether to use the json that cucumber wants or the version I have on my system… about half the time when I run bundle install I have to uninstall the mingw32 json gem. Sigh.

While figuring this out, I read this bundler bug wherein the Gemfile.lock (which you are supposed to check into your vcs) is generated differently on windows and linux/mac. The comments in that bug also show the subtle solution you’d have to use in your Gemfile to get the patched version of Nokogiri that is windows-only to work on all platforms:

gem "nokogiri", "~> 1.4.4"

so that you’ll get the latest version with bugfixes available on the platform you’re on.

Someone suggested being able to specify multiple versions of the same gem depending on the platform, and a bundler dev said that that goes against bundler’s reason for existence. I see that point, but saying something like (pseudocode) :windows => { gem “nokogiri”, “=1.4.4.1”} [:linux, :mac] => { gem “nokogiri”, “=1.4.4” } seems a lot more explicit and makes your app’s needs clearer, in the sense of conveying the reasoning behind that choice to future developers/users. I don’t know, hard problems are hard.

That bug says a solution for it is targeted for bundler 1.1 and that they are working on improving windows support, so that’s good.

cucumber + win32console, continued

Posted on

So since I didn’t have too much luck last night in getting win32console installed and Cucumber to recognize that I had win32console installed, I decided to try looking for the other problem I was seeing: “uninitialized constant win32”.

Googling that error message got me to this post which reminded me that I’m not working in Rails 2.3.x (like I do at my day job). So then I added win32console to my development group in my gemfile, did a bundle install, and rake cucumber then got me the 0 scenarios, 0 steps output without any errors.

While I was waiting for the rake cucumber to finish though (performance on windows is another thing I’d like to work on), I read through a few more results and saw that there’s a related bug in cucumber: this error happens on windows with ruby 1.9.2 even if you tell cucumber to not use color. Maybe that will be the next bug I work on.

Let’s try this again, shall we? win32console problems

Posted on

So after last night’s attempt to get a working windows+ruby+rails+cucumber environment and the blogging thereof, I was ready to make some real progress tonight.

No dice. I got through a handful more commands in the RSpec book before I hit another issue.

I got the rails generate rspec:install and rails generate cucumber:install to work last night. The next steps, on pg 288 (of printing 1), were these, to make sure everything was wired up correctly:

> rake db:migrate # worked fine

> rake db:test:prepare # worked fine

> rake spec # got the expected output about not having any *_spec.rb files

> rake cucumber # :(

I got 2 problems from this command: ‘You must “gem install win32console”’ and ‘uninitialized constant Win32 (NameError)’. Here’s a gist of the whole output.

I decided to ignore the uninitialized constant error for the moment and go install win32 console. I ran the command exactly as instructed, and saw this go by:

> gem install win32console
Temporarily enhancing PATH to include DevKit...
Successfully installed win32console-1.3.0-x86-mingw32
1 gem installed
Installing ri documentation for win32console-1.3.0-x86-mingw32...
Installing RDoc documentation for win32console-1.3.0-x86-mingw32...

And again:

> rake cucumber
...
*** WARNING: You must "gem install win32console" (1.2.0 or higher) to get coloured output on MRI/Windows
...

But I already did that!!! Why isn’t cucumber recognizing that I installed win32console?!?

I started by googling for:

  • i installed win32console but cucumber still

Remembering the lesson I just added to the previous post, I then searched the RubyInstaller google group for win32console. I found some talk about deprecating win32console.

That’s an interesting discussion for the future that I’m going to look into eventually. For now, I also found this ruby-forum post by Luis talking about a prerelease version of win32console. So I did gem uninstall win32console and gem install win32console –prerelease, then did rake cucumber again:

*** WARNING: You must “gem install win32console” (1.2.0 or higher) to get coloured output on MRI/Windows.

And my eyes are drooping faster than my fingers can google, so I’m going to get some rest. I’ll be back.

[BUG] cross-thread violation on rb_gc()

Posted on

The Problem:

When I ran:

> rails generate rspec:install

or

> rails generate cucumber:install

I got:

[BUG] cross-thread violation on rb_gc()
(null)

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

The Solution:

I found this post in the RubyInstaller google group where Luis Lavena had worked with someone else seeing the same issue, and he recognized it as a problem with the json gem version 1.4.6 x86-mingw32 not having binaries for Ruby 1.9.

His recommended fix, that worked for me, is to run:

> gem uninstall json

Then download and install DevKit for the Ruby installation I was using (I’m using pik and was trying to set up a new environment, see the details below)

Then run:

> gem install json --platform=ruby

And then the rails generate rspec:install and rails generate cucumber:install commands worked as expected.

Please comment if this post helped you with the same issue, or if you know how to fix this issue so that it won’t bite others in the future. I’m still a beginning Rubyist (I’ve gotten to a point where I’m starting to know how much I don’t know), and I’m definitely interested in working on this and other problems (which was my original intention of this evening!!!) but I don’t know exactly how to go about doing such things yet, in many cases.

More details:

I’m using pik, the Windows alternative to rvm. My overall goal was to create a new, clean pik environment in which I could create a new rails app using a clean gemset.

So I used the RubyInstaller (thank you again, Luis!) to install Ruby 1.9.2, then I added it to pik and switched to it.

Then I started installing– rails 3.0.3 and cucumber 0.9.4 (the gem I’m interested in reproducing a bug with/patching).

At that point I switched to following The RSpec Book starting on page 286 (of printing 1) which has you do:

> rails new <my-app>
> cd <my-app>

Modify your Gemfile to be:

source 'http://rubygems.org'

gem 'rails', '3.0.3'
gem 'sqlite3-ruby', :require => 'sqlite3'

group :development, :test do
gem 'rspec-rails', ">=2.0.0"
gem 'cucumber-rails', ">=0.3.2"
gem 'webrat', ">= 0.7.2"
end

Then run:

> bundle install

And then finally:

> rails generate rspec:install

And that is how I got to the cross-thread violation on rb_gc(). Phew.

How I got to the solution:

Google searches for:

  • rails generate rspec install bug cross-thread violation
  • "cross-thread violation on rb_gc"
  • pik ruby windows cross-thread violation rb_gc
  • +pik +ruby +windows +cross-thread +violation +rb_gc (yes, google, i really want ALL these terms to be in the pages you give me... what is this, 1997? That's another post...)
  • site:ruby-forum.com "cross-thread violation on rb_gc"
  • bug cross-thread violation dll (i had seen a dll having to do with 1.8 being referenced in the details of the crash as reported by windows)
  • bug cross-thread violation rb_gc dll

Stack overflow searches for:

  • [ruby] [cucumber] cross-thread violation
  • [cucumber] cross-thread violation
  • [rspec] cross-thread violation

I also looked at the issue trackers for pik and a lot of posts on the Ruby Forum.

I have now learned that the RubyInstaller google group is a good place to start looking for windows+ruby related issues.

Page 3 of 4