I woud like to make a Robot Framework project with multiple (levels of) test suits and test cases.
Is it possible to define a list of settings, specifically importing of libraries, resources and global variable (.py files), only once in one place?
As far as I'm aware this is not possible. You have to import libraries, resources and variable files explicitily in each .robot test case file that uses them. The init file in a directory can only be used for other settings, not imports.
But I would like to keep things DRY and import resourse that I use everywhere only once and in one place.
Is this not possible, or am I missing something?
Note: I'm still a RF newbie.
Thanks!
It's easily doable, and quite a common pattern - have a resource file, that has all the common keywords, variables, imports of other robot or py files, etc, and in every test suite - import it.
Say your project's directory structure is like this:
root_folder/
├── resources/
│ ├── common_resource.robot
│ ├── helpers.robot
│ ├── specific_page.robot
└── suites/
├── login_page.robot
└── specific_page.robot
The file resources/common_resource.robot has all those common elements - say, imports helpers.robot as a resource.
Every suite file imports the common file; e.g. both login_page.robot and specific_page.robot start-off with (path-relative) imports:
*** Settings ***
# other imports, documentation, etc
Resource ../resources/common_resource.robot
On top of that, each suite imports any other specific keyword files - like resources/specific_page.robot.
It's a convention, that once established ("every suite must import common_resource.robot") is easy to follow.
If there is a new keyword, variable or library that has to be used in all - or most - suites, just add it to the common file, and it will be instantly accessible.
Related
I'm trying to convert my previous qmake approach to cmake. I have a static lib called shared that links with different applications as a common ground. Each application has it's own static lib called common to link with the different targets of the same application (standalone, plugin-format-1, plugin-format-2, etc).
shared/
├── CMakeLists.txt
├── shared.cmake
│ .
project/
├── CMakeLists.txt
├── common/
├── common/CMakeLists.txt
│ common/common.cmake
│ .
When I'm developing and debbuging I want to avoid the hassle of compiling each lib individually so in debug mode I would usually include shared.pri and common.pri and when compiling the application, everything would compile smoothly, all toghether. I'm trying to replicate this include pattern using .cmake files.
#project.pro
include(../shared/shared.pri)
include(common/common.pri)
When I want to make a final and release version of the application I have a build script that compile the shared static lib, the common static lib and then links the different targets with this libs.
I have already created the CMakeLists.txt for the shared and common static libs. My problem now is how to replicate the pattern described above with cmake because when including the shared.cmake and common.cmake in the application CMakeLists.txt, the paths are not compatible. It seems that when you include(xxx.cmake), the path will always be relative to the parent CMakeLists.txt.
What would be the right way of achieving this with CMake? Is this even possible?
Use add_subdirectory() instead of include. For shared, which is "out-of-tree", you'll also need to specify the binary directory (the place to put the generated and compiled files).
add_subdirectory(../shared shared)
add_subdirectory(common)
Any targets created in those subprojects will now be available for you to link with target_link_libraries in your main project.
When you build your separate versions, consider using export() and/or install(EXPORT) to produce cmake files that you can include from your application projects instead of using add_subdirectory(), so that can be the only change you need to make.
There are SSR-related problems with several pages in Next.js project that results in errors on npm run build and prevent the project from being built:
pages/
foo/
bar/
[id].jsx
index.jsx
index.jsx
...
For example, bar:
export function getStaticProps() {
return someApiCallThatCurrentlyFails()
...
}
export default function Bar() {...}
As a quick fix, it may be convenient to just not build bar/*.* pages and make routes unavailable.
Can pages be ignored on Next.js build without physically changing or removing page component files in the project?
You can configure the pageExtensions in the next.config.js.
// next.config.js
module.exports = {
pageExtensions: ["page.js"],
}
After configuring this, the only pages with *.page.js will be considered in the below given directory structure.
pages/
├── user
│ └── setting
│ ├── index.js
├── _app.page.js
├── _document.page.js
├── list.page.js
└── theme.ts
Custom file ignores patterns that are not supported yet. You can visit the PR created here, and the solution given here. This is the most satisfactory solution so far.
#Mathilda Here from Nextjs docs: it's necessary for all pages including _app, _document, etc.
https://nextjs.org/docs/api-reference/next.config.js/custom-page-extensions
Changing these values affects all Next.js pages, including the following:
- middleware.js
- pages/_document.js
- pages/_app.js
- pages/api/
For example, if you reconfigure .ts page extensions to .page.ts, you would need to rename pages like _app.page.ts.
Currently I am working on a infrastructure in azure that comprises of the following:
resource group
application gateway
app service
etc
everything I have is in one single main.tf file which I know was a mistake however I wanted to start from there. I am currently trying to move each section into its own sub folder in my repo. Which would look something like this:
terraform-repo/
├── applicationGateway/
│ ├── main.tf
│ ├── vars.tf
├── appService/
│ ├── main.tf
│ └── vars.tf
├── main.tf
└── vars.tfvars
However when I create this while trying to move over from the single file structure I get issues with my remote state where it wants to delete anything that isn't a part of the currently worked on sub folder.
For example if I wanted to run terraform apply applicationGateway I will get the following:
# azurerm_virtual_network.prd_vn will be destroyed
Plan: 0 to add, 2 to change, 9 to destroy.
What is the correct way to setup multiple logically organized sub folders in a terraform repo? Or do I have to destroy my current environment to get it to be setup like this ?
You are seeing this issue because terraform ignores subfolders, so those resources are not being included at all anymore. You would need to configure the subfolders to be Terraform Modules, and then include those modules in your root main.tf
update 06/2022 , Complete example :
Let's say you have the following directories
./your-folder
|__ main.tf
|__ variables.tf
|__ output.tf
|__ /modules
|__ /module-a
|__ main.tf
|__ variables.tf
|__ output.tf
Module definition in ./your-folder/modules/module-a/main.tf:
resource "[resource_type]" "my-module-name" {
...
}
Load module in your root main.tf file, so in ./your-folder/main.tf:
module "my-module-instance-name" {
source = "./modules/module-a"
other-input-variable = "..."
}
Then tell Terraform to load this new module running the following command in your root directory (so ./your-folder):
terraform get
Then test your setup with terraform plan.
To use root-level resources in child modules, inject it into child module as input variable.
To use child-level resources in root module, export it from child module with the output instruction.
Hope this helps. :)
One option for maintaining a DRY environment this way is using Terragrunt
Terragrunt is a wrapper for Terraform that allows organization and reusable components in a slightly different way than Terraform handles environments.
I'll start with an example from PHP. Say I have a file structure like this:
.
└── includes
├── file.php
└── test.php
And say that my code looks like this:
// includes/test.php
require 'file.php';
// includes/file.php
echo 'SUBDIR';
Now, if I run php includes/test.php, I get SUBDIR as output. This is unsurprising.
But say I add a file at ./file.php that says echo 'ROOT!';. Now my tree looks like:
.
├── file.php
└── includes
├── file.php
└── test.php
And when I run php includes/test, it outputs ROOT!. I find this a bit astonishing.
When I think about it, what I find astonishing about it is not necessarily that file.php refers to something in the current working directory, but that before when it didn't find file.php in the current working directory, it looked in includes, relative to the file doing the require. It seems there is a subtle hierarchy to how PHP treats relative paths.
Note that if in includes/test.php I have require './file.php'; instead (a leading ./ where before there was just a "bare" file path), it works as expected IFF the "upper" file.php exists. That is, with a leading ./ it doesn't load includes/file.php and Fatal Errors.
Practically, all this boils down to: Don't use relative paths! Use absolute paths instead! That's not what I'm asking about.
What I'm wondering is, Is this just a UNIX thing? Is it enforced at the OS level, or simply by convention in programming languages? Do other languages behave differently?
Thanks.
It's never (or at least, very rarely) an operating system thing; most (maybe all) operating systems have a fixed an immutable method of resolving relative pathnames. It's almost always either a language thing or an implementation thing; that is, the behavior is documented either in the language standard or in the implementation manual.
For example, the behavior of PHP include and require is documented in the official PHP manual:
Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include [and require] will finally check in the calling script's own directory and the current working directory before failing.
If a path is defined — whether absolute (starting with a drive letter or \ on Windows, or / on Unix/Linux systems) or relative to the current directory (starting with . or ..) — the include_path will be ignored altogether. For example, if a filename begins with ../, the parser will look in the parent directory to find the requested file.
Other languages do it differently, of course. For example, in C and C++, #include directives are handled by the preprocessing step; the standards of those language explicitly say that the search for the file to be included is implementation-defined; the actual search rules are defined and documented by the specific compiler.
I made an app using the ionic framework and would like to make it run on meteor.
The App is build on top of the sidemenu template you can create tying ionic start myApp sidemenu.
Here is the Git of the port or just
> git clone https://github.com/Xample/sidemenu-meteor
> cd sidemenu-meteor/
> meteor
How to do so ?
Create both projects:
ionic start ionicProject sidemenu
meteor create meteorProject
Reorganise the files:
All the important files within a ionicframework comes into a www folder start to reorganise them to fit with the meteor good practices.
In the meteor root folder, create a client, server, css, and public folder
Copy the ionicProject/www/css files into the meteorProject/css
Copy all the js files, the main index.html and the templates files into the meteorProject/client folder
All the other files which only needs to be served (images, audio, documents) must be put into the meteorProject/public folder
The ionicProject/www/lib will be replaced by a meteor package. Do not include it.
The meteorProject/server folder will remain empty
Now we need to ensure meteor will load the app.js file before the other one.
Create the meteorProject/client/lib folder
Move the app.js file into that one
You should have the following structure:
├── client
│ ├── controllers.js
│ ├── index.html
│ ├── lib
│ │ └── app.js
│ └── templates
│ ├── browse.html
│ ├── login.html
│ ├── menu.html
│ ├── playlist.html
│ ├── playlists.html
│ └── search.html
├── css
│ └── style.css
├── public
│ └── img
│ └── ionic.png
└── server
Import the meteor packages:
meteor add urigo:ionic
That one will include other dependent packages below:
added mquandalle:bower at version 0.1.11
added urigo:ionic at version 0.0.6
added urigo:angular at version 0.4.8
added urigo:angular-ui-router at version 0.6.1
added tinytest at version 1.0.3
bower package allows to use the bower package manager. Well basically it is a tool to allow easily include other packages using a description file (which might be used by angular but not packaged for meteor yet) you will likely be using it for installing ngCordova. No need for this sidemenu port btw
ionic correspond to all the files we did not copied from the ionicProject/www/lib folder. Those are now included by default into your meteor project.
angular is basically the same as for ionic. Angular is now included into your meteor project as well + the 'angular-meteor' which will be useful for bootstrapping the app.
angular-ui-router same story but for the router. This will be mandatory to handle the url and forward them to the right page. It's a little bit like the Iron router but angular way and compatible
tinytest is added per default, no real need for the port
Edit and port the files
index.html
- On meteor the header and the body are parsed and generated back by the framework. In short, meteor packs everything and generate the script and style files for you. Conversely if you wanted to just include a css or a js file through a or tag within the header / body, they will be dismissed by meteor. This is the reason why we are using packages instead of adding our script by ourselves. This to say, that most of the content of the index.html is now useless and needs to be removed. Even the is not allowed by meteor because it will generate it for you as well…. Moreover, no attributes are allowed in the body. This might be problematic for bootstrapping our project with angularJS. The html files looks like this now:
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>sidemenu-meteor</title>
</head>
<body>
<ion-nav-view></ion-nav-view>
</body>
The templates files:
All the .html files not being into the server, public or private folder are loaded and packed into one big html by meteor. As meteor will search for and pack all the .html it will load but not include all the one within a <template> tag. All the files into the meteorProject/client/templates must be edited and encapsulated within a <template> tag bearing the name attribute such that we can easily find it back later on. For example the template browse.html will be packed such as:
<template name="browse.html">
... browse html file content ...
</template>
Repeat this step for all the templates.
app.js
Open the file and add the manual bootstrap for angularJS, in this manner you manually add the ng-app tag on top of the document.
Meteor.startup(function ()
{
angular.bootstrap(document, ['starter']);
});
Note: You need to do it once everything is loaded, for this reason we are doing it within the Meteor.startup function caller.
Add the 'angular-meteor' package to your application, this will change the Angular delimiters to [[ and ]] instead of the regular conflicting with meteor's handlebars {{ and }}
angular.module('starter', ['angular-meteor','ionic', 'starter.controllers'])
Replace the router's templateUrl path url references to something we can use with the loaded by meteor templates. Remember, we are not storing the templates into the meteorProject/public folder, therefore we cannot load them through templateUrl:'someUrl' you might do it but I do not recommend
templateUrl: "templates/menu.html", becomes template:UiRouter.template('menu.html'),
Repeat this step for all the states in the state provider.
controller.js
just replace the template dependency of the modal. From:
$ionicModal.fromTemplateUrl('templates/login.html', {
to
$ionicModal.fromTemplateUrl('login.html', {
This is again to ensure the template is found correctly. Note that for some reason we have been able to load the templateUrl using the template name. It's still a mystery to me, probably a meteor package port have added this sugar…
playlists.html (but possibly other files)
Edit all the files and replace all the {{ occurrences to [[ and }} to ]]
Basically in this example you will only have to edit playlists.html
Last step
At this stage you should be able to run the ionic sidemenu project under meteor. There is only one thing missing. As you can remember, we changed the delimiters {{}} -> [[]]. Unfortunately, some of the ionic directives are using the regular {{}} delimiters and expect them to be functional. Therefore while adding a <ion-item href="myPath"> this is compiled to something like <a href={{$href()}}> so… now if you click on a menu, the href will be wrong and you will not be redirected to the right page… To fix this, a workaround is to embed the <ion-item> within your own <a href="myRef"> tag. I'm still looking for a better solution…. Still to do so, just refactor all your ion-item such that:
<ion-item nav-clear menu-close href="#/app/search">
becomes encapsulated in
<a href="/#/app/search">
<ion-item nav-clear menu-close >
Search
</ion-item>
</a>
Dependencies
Last thing, meteor will try to minify your javascript during the deployment, doing so you might break the angular code if it is not using the array notation. Just refactor all your methods putting your methods into an array. Read the guide for more information. An alternative is to avoid meteor to minify the code deploying using --debug meteor deploy --debug your-project.meteor.com
To get this tutorial:
> git clone https://github.com/Xample/sidemenu-meteor
> cd sidemenu-meteor/
> meteor