Cucumber Transforms for Multiple Variable Scenario Outline Examples - ruby

I have a set of functionally similar websites that I want to write cucumber specs for to drive both development, and selennium browser tests. The site are in different languages and will have different URLs, but will have mainly the same features.
An example scenario might be
Scenario Outline: Photo Gallery Next Action
Given I visit a "<photo-gallery-page>"
When I click "<next-button>" in the gallery
Then the photo should advance
Examples:
| photo-gallery-page | next-button |
| www.site1.com/photo-gallery | Next |
| www.site2.com/la-galerie-de-photos | Suivant |
This is fine when I have a small number of scenarios and examples. However I'm anticipating hundred of scenarios and fairly regular launch of new sites. I want to avoid having to edit each scenario to add examples when launching new sites.
I think I need to store all my example variables in a per site configuration, so that I can run the same scenario against all sites. Then I can add new configurations fairly easily and avoid editing all the scenario examples and making them unreadable.
site[:en].photo-gallery-page = 'www.site1.com/photo-gallery'
site[:fr].photo-gallery-page = 'www.site2.com/la-galerie-de-photos'
site[:en].next-button = 'Next'
site[:fr].next-button = 'Suivant'
One option would be to store this config somewhere, then generate the site specific gherkin files using a script. I could then run these generated gherkins which would contain the required examples
I'm wondering if there's an easier way. My other idea was if I can use table transforms to replace the example blocks. I've had a read, but as far as I can tell I can only transform a table (and replace it with a custom code block) if it's an inline table within a step. I can't transform an examples block in the same way.
Have I understood that correctly? Any other suggestions on how best to achieve this?

I wonder if there's a better way... This all feels very brittle.
What if:
Given I follow a link to the gallery "MyGallery"
And the gallery "MyGallery" contains the following photos:
|PhotoID|PhotoName|
|1 |MyPhoto1 |
|2 |MyPhoto2 |
And the photo "MyPhoto1" is displayed
When I view the next photo
Then the next photo "MyPhoto2" should be displayed
Note that you've taken out the notion of button names, etc. - implementation details that are presumably better defined in your step definitions. The behaviour you're defining is simply going to a gallery, viewing an image, requesting the next one, viewing the next image. Define how in your step definitions.
There's some reading I found very useful on this topic at http://cuke4ninja.com/. Download the PDF and check out the web automation section (it details the web automation pyramid).
To address your configuration problem, maybe you could define some kind of config. class and supply it to the step definition files via dependency injection. You could make it site specific by loading from different config. files as you suggested in its constructor. Step definitions could pull the relevant site specific data from the config. class' properties. I think this would make your scenario is more readable and less brittle.

Related

How can I get a list of all CSGO items including skin name, quality and rarity?

I'm not looking for details of a specific player inventory, but a list of all items for CSGO. What I want is details of the weapons in particular, but including skin name information and rarity.
To make it easier to explain this site has the information I need, except rarity.
http://csgo.steamanalyst.com/list.php
By using the following api url I can get weapon model names but not skin names (ie. "Zirka")
http://api.steampowered.com/IEconItems_730/GetSchema/v0002/?key={YOUR_API_KEY}
I haven't found anything regarding skins in Steam Web Api.
Lists of all skins as well as rarity and corresponding weapons are in "paint_kits", "paint_kits_rarity" and "item_sets" sections of /csgo/scripts/items/items_game.txt file.
As for their correct names, those are in /csgo/resource/csgo_YOUR_LANGUAGE.txt. Looking like that
"PaintKit_so_red_Tag" "Candy Apple"
Won't be hard to make php or python script to get all of it and put it in a database for ease of use.
For skins images you could get weapon and skin name from the above, and do a foreach curl loop to get content from div with "market_listing_largeimage" class using for example simple_html_dom.php, from url http://steamcommunity.com/market/listings/730/{ITEM_NAME}%20%7C%20{SKIN_NAME}%20%28{USAGE_THINGY Ex. Well-Worn}%29
Just remember to replace all spaces going to the url with %20 but that depends on what you use to get the page. You could do a foreach on the usage thingy since some weapons don't have some variants on the market, curl could return wrong page. Nothing that a simple if+foreach couldn't fix.
Also do it only after skins update if overused you could get blocked from valve website for spamming. You could also use SteamWebApi and game news to check for new versions and update it automatically then. Just use your imagination and google.

How to serve static profile images in node

This is really more of a "using what method" than a "how-to" question. I am creating a site in NodeJS with Express. So, each user has the ability to upload a profile picture, and my concern is how to route requests for these images. A couple of questions I have are:
Can I use express.static() to serve a default file if a valid one isn't specified? If not, am I going to have to specify a GET route for /img/profileand handle the FS querying there?
How can I find the correct image if multiple file extensions are allowed? (I originally just removed the file extension and they appeared in img tags anyway, is that okay?)
I am currently naming all pictures after their user's name. Looking ahead into the future (for apps I may have to scale), what are normal naming conventions for static user content? Are most stored with a UUID referencing the content in the database?
What else should I take into consideration that I may not have accounted for yet?
First question:
At present, I'd recommend storing your images in a predictable location that can be inferred from some combination of columns or fields in your database entries. One of those fields or columns would be a filename (accounts for different extensions). Then, if they haven't uploaded an image, you just lay down in your view code a reference to the generic "has not set an image" file.
express.static obviously can server static files, but it currently doesn't have a way to serve some other file if the one you wanted isn't there. Because this sounded like fun, I made some modifications to static to support what you request and submitted a couple of pull requests (the feature touched 2 different modules):
In send: https://github.com/visionmedia/send/pull/33
In connect: https://github.com/senchalabs/connect/pull/999
I don't know if those will get included in the project, but if you want to see my forks that have these changes, they are here:
https://github.com/bigohstudios/send
https://github.com/bigohstudios/connect
If this went through, you would mount a static at the root of your profile image files:
app.use(static('<profile image files root>', { fallback: 'anon.jpg'}))
Second question
I generally store the extension in my DB, then when I load the image, I have the correct extension to put into the src attribute on the img tag.
Third question
If you can guarantee unique names, then using those would work. I prefer using the DB id or a UUID as you suggest. It's less intuitive when scanning all the image uploads, but I rarely find myself doing that. I'm usually hunting for a specific image, and I can look up the identifier for that as needed.
Fourth question
You may end up storing the static content outside your app server (e.g. on S3). If that happens, then of course static won't help you.

Parsing Jekyll's Categories

I have created a simple blog based on the Jekyll engine but I need one more function to make the thing really complete.
In Jekyll, parent directories of posts are implicitly 'labels' or 'categories'. So, if I were to create a post under the directory structure
/computers/scm/git
it would end up having 3 labels (computers, scm, git)
In my blog, I have created a few pages:
/computers/index.html
/computers/scm/index.html
/computers/scm/git/index.html
and these pages explicitly list posts in their respective categories such that /computers/index.html displays links to every post in /computers, /computers/sc and /computers/scm/git ... and likewise on down the road. Unfortunately, categories are not compound in Jekyll and so, "/computers/scm/index.html" iterates over the same set of posts as "/sandwiches/scm/index.html" …
Now, I'd like to automatically generate a sitemap listing all the categories, providing links to all of the pages I've created. Jekyll includes a construct "site.categories" that I can iterate over which works just great for all the top level categories. The problem is that when "scm" comes up, there is no "/scm/index.html" - it needs to be "/computers/scm/index.html".
I'm not sure I can fix this behavior - what type of extensions can I write to get both hierarchical categories and automatically generate a site map to my listing pages?
In my wildest dreams, I'd like to be able to tag a post as /a/b/c and have it associated with labels /a, /a/b and /a/b/c and then be able to generate pages that iterate over exactly these sets of posts. I need the site's organization to drill down from general to specific.
Do I need to try a different static generation engine?
You need to use Jekyll's plugins. For categories support in my blog I use one of this.
If you are Github Pages user, you must note that GP does not support plugins because of security reasons. To avoid this, you may use ideas from this blog post.
As an alternative, you can use Octopress, which is Jekyll-based.

Cucumber Features and Step Definitions

I am new to Cucumber testing.
I have created two features files:
events.feature
partner.feature
and have my step definitions in a step_definitions folder:
./step_definitions/
events.rb
partner.rb
It seems that Cucumber looks in all the .rb files for the step information.
Is there anyway of restricting the feature to look at a specific step definition file?
The reason as to why I want to do this, is because I am getting Ambiguous match errors, even when I use the --guess flag.
The reason as to why I want to do this is for the following reasons. I am testing a CMS, and want to test each of the different content types (events & partners) in separate features.
events.feature
Feature: Add partner
As an administrator I can add a new partner
Scenario: Create partner
Given I am logged in
When I create a partner
Then I should see content
partner.feature
Feature: Add event
As an administrator I can add a new event
Scenario: Create event
Given I am logged in
When I create an event
Then I should see content
Just focusing on the 'then I should see content' which is in both scenarios, the error occurs because in the .rb files I need to include:
partners.rb
Then /^I should see content$/ do
BROWSER.html.should include('SOME PARTNER CONTENT')
end
events.rb
Then /^I should see content$/ do
BROWSER.html.should include('SOME EVENT CONTENT')
end
which means there is an Ambiguous match of "I should see content".
I understand there are different ways of structuring this, i.e. I could create a content feature, and use scenario outlines:
Feature: Add content
As an administrator I can add a new content
Scenario Outline: Create content
Given I am logged in
When I create an <content type>
Then I should see <example content>
Examples:
|event |March Event |
|partner |Joe Blogs |
But I don't want to do this because I want to encapsulate each content type in their own test feature.
So essentially I need to work out how to run specific step files according to the feature I am testing.
Cucumber always loads all files and I don't think that there is a way to override this behavior. Regarding your problem with ambiguous steps - the solution is easy - add parameters to your steps
Then /^(?:|I )should see "([^"]*)"$/ do |text|
page.should have_content(text)
end
And in scenarios just call it like this
Then I should see "PARTNER CONTENT"
free bonus - your scenario is now much more readable
I don't see anything wrong with the alternative approach that you suggested. Separating out the step definitions into logical domains makes sense. However, it seems like you may be trying to take it too far, and that's going to lead to a good deal of duplicated code and issues with ambiguous matches like you're seeing now. I'd recommend doing something like this:
Feature: Add partner
As an administrator I can add a new partner
Scenario: Create partner
Given I am logged in
When I create a partner
Then I should see "partner content"
And, similarly, in your event feature:
...
Then I should see "event content"
Then you could the following in a separate step_definitions/common_steps.rb file:
Then /I should see "(.*)"$/ do |content|
BROWSER.html.should include(content)
end
This step doesn't have anything partner/event specific about it. Instead, the scenarios contain the data-specific strings for your features.
If you are working on a Rails app, the cucumber-rails gem will actually create a bunch of common steps for web application testing for you. Even if you aren't using Rails, it might be useful to take a look at some of these steps.
I've been looking for this, but it appears not to be possible "out of the box".
My solution is to differentiate steps always using some kind of additional description, such as class name, for example:
Scenario: Buildings List
Given I have a Building with code "B1"
And I have a Building with code "B2"
When I go to the list of buildings
Then I should see "B1" building code
And I should see "B2" building code
These "building code" descriptions are all you need not to reuse steps between different files / domains.

codeigniter extra url segments

I am making a site for a client and decided i would use code igniter.
The site essentially has two backends, one for designers, and one for a sales team. So after logging in, the user will be redirected to either
mysite.com/sales/
mysite.com/design/
The sales team for example can view orders, containers, products, therefore i need a controller for each of these.
mysite.com/sales/orders/
The sales need to be able to view, edit, delete certain orders...
mysite.com/sales/orders/vieworder/235433
Basically my problem is i dont have enough url segments to play with.
My thoughts on solving my problem
removing the orders, containers, products classes and making ALL of their methods as methods of the sales class, although this would mean a large number of methods and loading all models so it seemed kind of pointless.
removing the sales/designer classes and controlling what each kind of user has access to based on a user type stored in session data.
a way of having an extra url segment?
I appreciate any advice, I just dont want to get 3 weeks into the project and realise i started wrong from the beginning!
Use folders.
If you make a subfolder in /application/ called sales you can put different controllers in there:
/application/
/sales/
orders.php /* Controller */
/design/
Then in orders.php you will put your vieworders($id) method and so on, and you will be able to acces it with domain.com/sales/orders/vieworders/id.
You can also make subfolders in the /models/ and /views/ to organize your files.
Now, Access Control is something apart and it depends more in the auth system you are using.
Give the user/designer a privilege, a column in the user table for example, check the permission of the user at the beginning of the function, then prevent or execute it.
This would be the exact way i would do it.
Seems like you should have a look into the routing class. Might be a dirty solution but rerouting the sales/(:any) to something like sales_$1 would mean you'd make controllers with names like sales_orders.
Same for the design part.
(FYI: $routing['sales/(:any)'] = 'sales_$1'; should do the trick; see application/config/routing.php).

Resources