Notes on Xpath / XML with css

Xpath adventures!

I was using a chunk of code that I found to be rather brittle for testing Xpath with Capybara in a ruby on rails integration test.  Originally I was just calling click_link on the first link within the .body tag.

The problem is that’s really brittle.  Any other links put in there before that will mess up the process.  Also, if I make that page a partial so I can reuse that particular list on other pages, then my test is broken.

So my practice now is to add a class or div to the top of all partials or pages even if I have the body & nothing else is in that page.

An example:

The partial _campaign.html.haml would have a .campaigns at the top wrapping it.  Then my html/css parsing with Xpath would be `.campaigns` to get into the section of the list I want to affect.

For my purposes that’s enough.  If you want to go deeper though – as you have more elements inside & need to be selective, then you would add more path hierarchy … .campaigns/.list-group/.list-group-item[1] … with the last [1] being select the first item in the list group.

Xpath best practices is to not stack too many or any nested items so they use within.  Still, probably best to only use two within‘s one to grab the first unique class/div name & the next to grab the last div or element before running the method against the result.

  • Instead the previous campaigns example, using the within would be combined with something else….
within('.campaigns') do
  first('.list-group-item').click_link('Join') 
end

Also, as a bonus I had to figure out the calls for using spaces in the names/titles.  There are two methods I like.

  • Exact matching with “multiple class selectors”… .something/.something_else – Link.
  • Matching Xpath to just search a string for a partial match with the xml/css  – Link.  I would still scope the search/match pattern (2nd method) by using a .within anyways as the whole point is avoiding brittle tests.
Advertisements

First time unity video game development Tic Tac Toe

I’m an hour & a half in now … just about to implement the win conditions on the Tic Tac Toe tutorial.

  • Explanation of the UI behaviors from Unity professionals – Link – not necessary for the Tic Tac Toe demo – would skip till later if you like to move fast, as it’s not needed for simple games.
  • Tic Tac Toe game tutorial using UI only – some limited scripting – Link
    • UY studio’s – Computer read version of the tutorial with mouse demo’ing where to click & explain several necessary items. – Link

 


First 20 watched & read ahead of demo on the UI behaviors

Next hour – followed along with the youtube link by automated reading voice to get a board fleshed out & some of the Game Controller scripts.

Next half hour – followed along with UY Studio’s to create scripting for GameEngine in 3 videos.

Next half hour – made my own C# script to simplify the end game checks (as they looked scary) …

void check3InRow(string button1, string button2, string button3)
 {
  if (button1 == button2 && button1 == button3)
   {
    if (playerSide == button1)
     {
      GameOver();
     }
   }
 }

I then fed in the win conditions with this chunk of code …

public void EndTurn()
 {
 /* Test row wins */
 check3InRow(buttonList[1].text, buttonList[2].text, buttonList[3].text);
 check3InRow(buttonList[0].text, buttonList[4].text, buttonList[8].text);
 check3InRow(buttonList[5].text, buttonList[6].text, buttonList[7].text);

/* Test column wins */
 check3InRow(buttonList[1].text, buttonList[7].text, buttonList[8].text);
 check3InRow(buttonList[0].text, buttonList[2].text, buttonList[6].text);
 check3InRow(buttonList[3].text, buttonList[4].text, buttonList[5].text);

/* Test diagnal wins */
 check3InRow(buttonList[0].text, buttonList[1].text, buttonList[5].text);
 check3InRow(buttonList[0].text, buttonList[3].text, buttonList[7].text);
 }

Next 10 minutes researching.

Finding the class based on an object instance of the object in Rails with Constantize

Trying to write a rails method to count the rows in a table.

The twist:  I want to do it in such a way that I can call the method from any object and it will automatically determine the name of the table to count the rows from.

Basic outline of the flow … I want to use Rails Way to identify the table & count the resulting table name’s rows.

Model.count

To do so I need the name of the model.  As my test object, I cleverly naming it anObject

2.3.1 :040 > anObject = Player.first
 Player Load (2.4ms) SELECT "players".* FROM "players" ORDER BY "players"."id" ASC LIMIT $1 [["LIMIT", 1]]
 => #<Player id: 1, screenname: "Serena Mitchell I", motto: "Wyaaaaaa.", country_id: nil, created_at: "2017-09-01 12:52:27", updated_at: "2017-09-01 12:52:27">

Rails has several definitions which hold that information in various states.  I chose to use .class …

2.3.1 :043 > anObject.class
 => Player(id: integer, screenname: string, motto: string, country_id: integer, created_at: datetime, updated_at: datetime)

When we look at this, it’s more information than we need.    The Rails Way is to call the .name method out of the class method …

2.3.1 :046 > anObject.class.name
 => "Player"

As a bonus .name gives us access to .constantize which is the goal.

2.3.1 :048 > anObject.class.name.constantize
 => Player(id: integer, screenname: string, motto: string, country_id: integer, created_at: datetime, updated_at: datetime)

Now we can put .constantize to search all the Rails app’s constants …

2.3.1 :050 > anObject.class.name.constantize
 => Player(id: integer, screenname: string, motto: string, country_id: integer, created_at: datetime, updated_at: datetime)

… which when proceeded by the .class.name will give the activerecord model as an object which we can then .count against …

2.3.1 :052 > anObject.class.name.constantize.count
 (0.8ms) SELECT COUNT(*) FROM "players"
 => 46

At this point .class.name.constantize should net us what we need, so I wrap it in a method for easy reuse …

#  gets name of constant to get a count of model
def row_count(ar_object)
  ar_object.class.name.constantize.count
end

This of course isn’t perfect, if ever you had an conflict in the naming scheme, scope issues or an orphaned object from the inheritance tree, the .constantize search up the object inheritance tree would fail even though your object exists.

Note there is another way, that if you are only doing ActiveRecord objects works too … Link.  My example is slightly more generic example as you can use it to find other types of objectives – though you can’t use the count method with most of them.

The reason you would use it, is that it’s more self documenting, thus more in line with the Rails Way ….

# .model_name.name is basically the same as .class.name for this purpose
ar_object.model_name.name.constantize.count

My studies from other authors which I found helpful, in no particular order …

  • Failure points & discussions for constantize – Link
  • Implementing in a custom module from Stackoverflow – Link
  • Implementing the constantize lookup in depth & use – Link
  • Safelty constantize in forms, aka don’t – Link
  • Metaprogramming & testing with constantize – Link

Rails organization / patterns

Been summarizing some of my studies – note none of this is confirmed by an official Ruby on Rails historian …

I started out looking for where code was supposed to be placed.  Why?  Because I read about DRY.  I really liked the idea of not wasting time redoing code – it’s one of the reason I got into Rails, which I will call RoR from here forward.

So people divide the RoR apps up according to MVC philosophy, which the short version is the model of the database logic, the view you see & is’ logic, and the controller with its logic to tie the two together.

In this MVC design, when I entered RoR’s world most posters were talking about Fat Model / Skinny Controller.

I started reading a lot about this stuff … Justin Weiss has a great breakdown summary of different patterns & where they get placed in the RoR app – Link.  I also like the description of the process on Stackoverflow from ‘Jason‘ & Mike Woodhouse – Link.

 

From what I can gather from posts there was a development of programming as people moved along.  Notice I’m not numbering these…there’s a reason…

  • model / controller / views
  • helpers (with special visibility to only their views)
  • custom classes anywhere
  • app/lib as “the spot” which at one point in RoR history auto loaded (not anymore)
  • modules / mix-ins to include the classes/methods
  • gems – which
  • plugins – which were discontinued in Rails 4, but the command used to make engines now – Hawkins had a good break down if somewhat biased – Link
  • concerns – which even had a special activesupport::concerns for including classes added
  • rails engines which improve on the modules>gems by encapsulating the database too … often these are wrapped in gems when created with mountable option – this might be part of the micro-services movement…

Trouble shooting reminders for me…

Trouble shooting

  • Did something actually break?
    • Is it perspective/perception thing instead of a solid problem?
    • Is it that you don’t have data/values or they aren’t being connected?
    • What does tail’ing the test/development log files show?
  • State changes
    • Does a reload / restart of server / using other device fix it
  • Where is the break at based on what is affected?
    • Can you output flags or sentences to help identify where firing?
  • Scope
    • How many things  affected?
    • How deeply or totally were things affected?
  • What was your last change?
    • What was your last commit to that branch?
  • Similarities / Shared in the systems / characteristics of  the affected systems / components
  • Can you comment stuff out until it works?
  • Does changing test coverage or stubbing work?
  • Does using the code in isolation work?