Create a Table with highlighted Source Code in Asciidoc - ascii

I would like to highlight some of my code in tables. I tried many ways but I could get it fixed.
I would appreciate if someone can help me.

great question!
Most AsciiDoc syntax is not rendered inside a table, only basic syntax like *bold*.
You have to explicitly tell Asciidoctor to render the whole feature set.
There are two ways to do so:
1) prepend the character a to the | of the cell where you want Asciidoctor to render the full syntax
2) configure a whole column to be rendered as AsciiDoc by stating your wish in front of the table: [cols="a,a"] will render a AsciiDoc in both columns of a two column table.
here is a gist to demonstrate this:
https://gist.github.com/rdmueller/b79f4b00890f75644a0186c4adda589a
docs can be found here: https://asciidoctor.org/docs/user-manual/#cols-format
Examples:
|====
|Col1 | Col2
| even complex formattings like source code highlighting works this way
a|
[source, groovy]
----
5.times {
println it
}
----
|====
[cols="a,a"]
|====
|Col1 | Col2
| even complex formattings like source code highlighting works this way
|
[source, groovy]
----
5.times {
println it
}
----
|====
See the gist for a rendering of these examples

Related

How to use previously created objects in Gherkin?

I have a class named QuestionGroup which contains a list of Questions. supposing it has the following structure:
+QuestionGroup
-Title
And a class named Question like this:
+Question
-Title
-Description
-QuestionGroupId
And a class named InteractionGroup which contains a list of Employees:
+InteractionGroup
-Title
and a class named Employee with:
+Employee
-FirstName
-LastName
-InteractionGroupId
and I have a class named AppraisalTemplate . it contains a list of QuestionGroups and a list of InteractionGroups.
+AppraisalTemplate
-Title
-List<QuestionGroup>
-List<InteractionGroup>
now I want to write a specflow feature in which I need to create an AppraisalTemplate before my scenario runs.
my scenario depends on this AppraisalTemplate because in order to execute my When step in the scenario those steps should be processed already.
now this is the feature I have written (steps are not written yet):
Feature: Appraisals
Background:
Given I have an QuestionGroup with Title '<QuestionGroupTitle>' and following Questions
| Title | Description |
| Question 1 | Desc Test 1 |
| Question 2 | Desc Test 2 |
And an InteractionGroup with Title '<InteractionGroupTitle>' and following employees
| FirstName | LastName |
| Clubber | Lang |
| Mickey | Goldmill |
And an AppraisalTemplate with Title '<AppraisalTemplateTitle>' and following QuestionGroup and InteractionGroup
#What should I write here?
Scenario Outline: [add a new appraisal]
Given [given]
When [when]
Then [then]
I was wondering how should I write the 3rd Given step in Background section?
I want to say
Given I have created an AppraisalTemplate with the **mentioned QuestionGroup(s) and InteractionGroup(s) in the last two steps**
How can I do it?
How can I execute a step and use a previously created objects in it?
Maybe I've misunderstood the whole story. If you would please explain me if there is a mistake in my feature as well.
thank you for your time
First of all you should try and simplify you scenario to
Not use example groups
Not use scenario outlines
This will remove lots of complexity which distracts from your core question
Then you should focus on the behaviour you are trying to exercise, which seems to be about filling in an Appraisal.
Then write your Givens and Thens
So ...
When I fill in my appraisal
To do this we might have something like
Given my appraisal is due
and we would implement this with something like
Given "my appraisal is due" do
#appraisal = create_appraisal(user: #I)
end
Now this requires me to be somebody, perhaps an employee
Given I am an employee
And my appraisal is due
When I fill in my appraisal
Then ...
and we can implement that Given with
Given "I am an employee" do
#I = create_employee
end
So now we have left just the idea of creating an appraisal
module AppraisalStepHelper
def create_appraisal(user: )
...
end
end
World AppraisalStepHelper
Notice how there is nothing to do with HOW you interact with an appraisal in our feature or step definitions.
So overall we have
Feature: Employee appraisals
...
Scenario: Fill in appraisal
Given I am an employee
And my appraisal is due
When I fill in my appraisal
Then ...
Now you will probably need a load of over features to allow you to get to here. For example
Feature: Schedule An Appraisal
Feature: Create Appraisal Template
...
There are several important points to note here
cuking is about specifying WHAT you are doing and WHY its important. Its not about specifying HOW things are done
good cukes are simple and easy to read
you want to deal with one small piece of business behaviour in each feature e.g. fill in my appraisal
you simplify by
abstracting
pushing the HOW down (into step definitions and helper methods)
choosing smaller chunks
each Given builds upon a previous when
You need to change your approach to Cuke effectively. Your current approach will overwhelm you with complexity. Hopefully the stuff above helps. Good luck

wkhtmltopdf from list of files generates wrong TOC based on H tags

I am using python-pdfkit as follows to generate a PDF:
pdfkit.from_file(list_of_files, toc=toc, cover=cover, cover_first=True, options=default_options)
My problem is regarding the table of contents that is generated:
The table of contents is generated based on the H tags in the input
documents
If my html files are like:
index1.html
<h1>Title</h1>
...
[content]
index2.html
<h2>Subtitle</h2>
...
[content]
index3.html
<h3>Sub-subtitle</h3>
...
[content]
Since they are 3 different files, then the generated TOC is:
Title --------------------- Page x
Subtitle ------------------ Page y
Sub-subtitle -------------- Page z
Instead of
Title--------------------- Page x
Subtitle -------------- Page y
Sub-subtitle ------- Page z
I have tried merging all html files together but it is giving me a lot of problems with the internal links... linking to files instead to HTML #IDs gets tricky with a single HTML file all merged.
Any idea how to tell wkhtmltopdf to respect the H tags hierarchy without resetting it per file?
Thanks!
Edit:
After some discussion in the wkhtmltopdf github issues section, the only easy way of achieving this result is pre-parsing the HTML files to merge them all together.
See the following link for more details:https://github.com/wkhtmltopdf/wkhtmltopdf/issues/4310

asciidoc: Including bold inside Code Fence

Ho can I include inside an asciidoc code fence? Here is a sample:
[source,js]
----
function doit() {
*var thing;* // local variable
}
----
The idea is that I would like to highlight certain parts of the code block for teaching purposes.
The above sample doesn’t work.
I have read about using something like [subs="macro"], but (a) I can’t get it working in combination with a code fence, and (b) the documentation is a little unclear about the actual details.
Thanks
BTW I am aware of a similar question AsciiDoc add bold text inside a listing block, but there is no reference to code fences. I have tried the solutions, but the don’t work in this context.
According to AsciiDocs Documentation, below code
[source,java,subs="verbatim,quotes"]
----
System.out.println("Hello *bold* text").
----
will be displayed as
System.out.println("Hello bold text").
So, you need this -
[source,js,subs="verbatim,quotes"]
----
function doit() {
*_var thing;_* // local variable
}
----
It will be displayed as
verbatim and quotes subs are helpful.
NOTE:
One thing we need to keep in mind that the code block is already highlighting syntax. If you want different formatting, better not to use code block.
In my opinion the philosophy of Asciidoctor for those use case is to use callouts.
[source,js]
----
function doit() {
var thing; // <1>
}
----
<1> local variable
The second thing you should consider is to extract your code from a real, controled, unit-tested file. You define some markers in this code file and add an include directive in your adoc file.
Check slides 15-21 in this presentation:
Writing documentation with Asciidoctor

Can I export descriptive test names in Selenium / Gherkin / Cucumber?

I have a few tests in feature files that use the Scenario Template method to plug in multiple parameters. For example:
#MaskSelection
Scenario Template: The Mask Guide Is Available
Given the patient is using "<browser>"
And A patient registered and logged in
And A patient selected the mask
When the patient clicks on the "<guide>"
Then the patient should see the "<guide>" guide for the mask with "<guideLength>" slides
Examples:
| browser | guide | guideName | guideLength |
| chrome | mask | Mask | 5 |
| firefox | replacement | Mask Replacement Guide | 6 |
| internetexplorer | replacement | Mask Replacement Guide | 6 |
Currently, this is exporting test results with names like "TheMaskGuideIsAvailableVariant3". Is there any way to have it instead export something like "TheMaskGuideIsAvailable("chrome", "mask", "Mask", "5")"? I have a few tests which export 50+ results, and it's a pain to count the list to figure out exactly which set of parameters failed. I could have sworn the export used to work like this at one time, but I can't seem to replicate that behavior.
Possibly tied to it, recently, I've lost the ability to double-click on the test instance in Test Explorer in Visual Studio and go to the test outline in its file. Instead, nothing happens and I have to manually go to that file.
The answer to the Variant situation is that the part that gets appended is the first column of the table. If there are non-unique items in the first column, it gets exported as numbered "Variants".
The answer I found to exporting the list is to use vstest.console with the "/ListTests" option. As per the prior paragraph, since the first column is the one to be used for naming, a column can be established with a concatenated list of parameters.

Cucumber load data tables dynamically

I am currently trying to use cucumber together with capybara for some integration tests of a web-app.
There is one test where I just want to click through all (or most of) the pages of the web app and see if no error is returned. I want to be able to see afterwards which pages are not working.
I think that Scenario outlines would be the best approach so I started in that way:
Scenario Outline: Checking all pages pages
When I go on the page <page>
Then the page has no HTTP error response
Examples:
| page |
| "/resource1" |
| "/resource2" |
...
I currently have 82 pages and that works fine.
However I find this approach is not maintable as there may new resources and resources that will be deleted.
A better approach would be to load the data from the table from somewhere (parsing HTML of an index page, the database etc...).
But I did not figure out how to do that.
I came across an article about table transformation but I could not figure out how to use this transformation in an scenario outline.
Are there any suggestions?
OK since there is some confusion. If you have a look at the example above. All I want to do is change it so that the table is almost empty:
Scenario Outline: Checking all pages pages
When I go on the page <page>
Then the page has no HTTP error response
Examples:
| page |
| "will be generated" |
Then I want to add a transformation that looks something like this:
Transform /^table:page$/ do
all_my_pages.each do |page|
table.hashes << {:page => page}
end
table.hashes
end
I specified the transformation in the same file, but it is not executed, so I was assuming that the transformations don't work with Scenario outlines.
Cucumber is really the wrong tool for that task, you should describe functionality in terms of features. If you want to describe behavior programmatically you should use something like rspec or test-unit.
Also your scenario steps should be descriptive and specialized like a written text and not abstract phrases like used in a programming language. They should not include "incidental details" like the exact url of a ressource or it's id.
Please read http://blog.carbonfive.com/2011/11/07/modern-cucumber-and-rails-no-more-training-wheels/ and watch http://skillsmatter.com/podcast/home/refuctoring-your-cukes
Concerning your question about "inserting into tables", yes it is possible if you
mean adding additional rows to it, infact you could do anything you like with it.
The result of the Transform block completely replaces the original table.
Transform /^table:Name,Posts$/ do
# transform the table into a list of hashes
results = table.hashes.map do |row|
user = User.create! :name => row["Name"]
posts = (1..row["Posts"]).map { |i| Post.create! :title => "Nr #{i}" }
{ :user => user, :posts => posts }
end
# append another hash to the results (e.g. a User "Tim" with 2 Posts)
tim = User.create! :name => "Tim"
tims_posts = [Post.create! :title => "First", Post.create! :title => "Second"]
results << { :user => tim, :posts => tims_posts }
results
end
Given /^I have Posts of the following Users:$/ do |transformation_results|
transformation_results.each do |row|
# assing Posts to the corresponding User
row[:user].posts = row[:posts]
end
end
You could combine this with Scenario Outlines like this:
Scenario Outline: Paginate the post list of an user at 10
Given I have Posts of the following Users:
| Name | Posts |
| Max | 7 |
| Tom | 11 |
When I visit the post list of <name>
Then I should see <count> posts
Examples:
| name | count |
| Max | 7 |
| Tom | 10 |
| Tim | 2 |
This should demonstarte why "adding" rows to a table, might not be best practice.
Please note that it is impossible to expand example tags inside of a table:
Scenario Outline: Paginate the post list of an user at 10
Given I have Posts of the following Users:
| Name | Posts |
| <name> | <existing> | # won't work
When I visit the post list of <name>
Then I should see <displayed> posts
Examples:
| name | existing | displayed |
| Max | 7 | 7 |
| Tom | 11 | 10 |
| Tim | 2 | 2 |
For the specific case of loading data dynamically, here's a suggestion:
A class, let's say PageSets, with methods, e.g. all_pages_in_the_sitemap_errorcount, developing_countries_errorcount.
a step that reads something like
Given I am on the "Check Stuff" page
Then there are 0 errors in the "developing countries" pages
or
Then there are 0 errors in "all pages in the sitemap"
The Then step converts the string "developing countries" into a method name developing_countries_errorcountand attempts to call it on class PageSets. The step expects all _errorcount methods to return an integer in this case. Returning data structures like maps gives you many possibilities for writing succinct dynamic steps.
For more static data we have found YAML very useful for making our tests self-documenting and self-validating, and for helping us remove hard-to-maintain literals like "5382739" that we've all forgotten the meaning of three weeks later.
The YAML format is easy to read and can be commented if necessary (it usually isn't.)
Rather than write:
Given I am logged in as "jackrobinson#gmail.com"
And I select the "History" tab
Then I can see 5 or more "rows of history"
We can write instead:
Given I am logged in as "a user with at least 5 items of history"
When I select the "History" tab
Then I can see 5 or more "rows of history"
In file logins.yaml....
a member with at least 5 items of history:
username: jackrobinson#gmail.com
password: WalRus
We use YAML to hold sets of data relating to all sorts of entities like members, providers, policies, ... the list is growing all the time:
In file test_data.yaml...
a member who has direct debit set up:
username: jackrobinson#gmail.com
password: WalRus
policyId: 5382739
first name: Jack
last name: Robinson
partner's first name: Sally
partner's last name: Fredericks
It's also worth looking at YAML's multi-line text facilities if you need to verify text. Although that's not usual for automation tests, it can sometimes be useful.
I think that the better approach would be using different tool, just for crawling your site and checking if no error is returned. Assuming you're using Rails
The tool you might consider is: Tarantula.
https://github.com/relevance/tarantula
I hope that helps :)
A quick hack is to change the Examples collector code, and using eval of ruby to run your customized ruby function to overwrite the default collected examples data, here is the code:
generate-dynamic-examples-for-cucumber
drawback: need change the scenario_outline.rb file.

Resources