Navigating from Feature file to step defination: Any Plugins - javascript

In visual studio cod, How to navigate from feature to step definition. Do we need any additional plugins or any configuration needs to be added. I have downloaded the Cucumber (Gherkin) Full Support plugin but still cannot navigate from .feature to the step definition.

The documentation of Cucumber (Gherkin) Full Support plugin has the explanation for it.
You need to add the below in your settings:
{
"cucumberautocomplete.steps": [
"test/features/step_definitions/*.js",
"node_modules/qa-lib/src/step_definitions/*.js"
],
"cucumberautocomplete.syncfeatures": "test/features/*feature",
"cucumberautocomplete.strictGherkinCompletion": true
}
cucumberautocomplete.steps => provide the path of the step definitions.
cucumberautocomplete.syncfeatures => provide the path of the feature files
After this(might be after a restart), cmd + click(on mac) would take to the step definition.
Thanks,
Naveen

Having installed the extension alexkrechik.cucumberautocomplete, I tried modifying the settings from both the UI of the extension and its corresponding settings JSON (by default, mine were in ~/.config/Code/User/settings.json). But this didn't work because I got this error in the *.feature files: Was unable to find step for "Some feature description".
I noticed I had skipped a step mentioned in the extension docs... By default, it was getting the settings.json from my userspace and not my work(project)space.
For me, the solution was to go to the root directory of my project (usually outside of /src, where you have the package.json and node_modules/) and create a .vscode/ folder. Then, create a settings.json file and paste there the cucumberautocomplete configuration with the paths relative to this brand new file.
Below I show a schema:
myProject/
├── node_modules
├── package.json
├── subdir1
│ ├── src
│ └── test
│ └── e2e
│ └── src
│ ├── features
│ │ └── myfeature1.feature
│ ├── mypageobject1.po.ts
│ └── steps
│ └── mystep1.step.ts
└── .vscode
└── settings.json
An example of configuration would be:
{
"editor.detectIndentation": false,
"window.zoomLevel": 0,
"cucumberautocomplete.steps": [
"subidr1/test/e2e/src/steps/*.steps.ts"
],
"cucumberautocomplete.syncfeatures": "subidr1/test/e2e/src/feature/*.feature"
}
Note that you could use **/*.steps.ts and **/*.feature paths but every time the extension settings file changes, when you Ctr + Click on a feature description, you will need to wait for the editor to resolve the paths. Otherwise, there is no waiting time.

Related

How to Dynamically Fetch Files with WebPack and Exclude Directories (node_modules)

TL;DR - We have ran into an issue with Storybook inside of a Monorepo
whose packages are independently versioned where the problem surrounds
Storybook running out of memory when it tries to scan for
*.stories.js due to it scanning every package's node_modules
directory. require.context() doesn't allow for exclusion to the
point where it won't scan the node_modules directories and we
couldn't find a native webpack solution to this problem - nor could we
find any existing discussion points around this problem, whose
solution wasn't just require.context('.', true,
/^\.\/((?!node_modules).)*\.stories\.js$/). We're posting our
discovery and potentially solution to see if anyone in the community
has had to solve a similar problem, and see if we are missing
something/making it harder than it needs to be.
The problem that we are trying to solve for is that Webpack's require.context() method does not allow for excluding specific directories from being scanned. For our project set-up, we are utilizing Lerna to manage a monorepo a JavaScript packages that are all independently versioned. Our file tree looks like this:
.
├── config
│ └── storybook
└── packages
└── vue
└── components
├── example-component
│ ├── node_modules
│ │ └── ...
│ ├── test
│ │ ├── example.stories.js
│ │ └── index.spec.js
│ ├── index.vue
│ └── package.json
└── example-parent
├── example-component-2
│ ├── node_modules
│ │ └── ...
│ ├── test
│ │ ├── example.stories.js
│ │ └── index.spec.js
│ ├── index.vue
│ └── package.json
└── example-component-3
├── node_modules
│ └── ...
├── test
│ ├── example.stories.js
│ └── index.spec.js
├── index.vue
└── package.json
For our storybook configuration, we need to tell Storybook where each of the components' *.stories.js file lives. We want/need the solution to be dynamic in a sense where if we add a new component into the directory tree in the same fashion, Storybook should automatically find the new *.stories.js without having to update Storybook's config file.
The option that Storybook suggests, is to use the require.context(String directory, boolean isDeep, RegEx fileMatch) method that is a part of webpack. However, when isDeep is set as true you are unable to restrict the method from scanning particular directories, like node_modules, due to the fact that the directory parameter is a string and not RegEx. Understandably, a regex match for the directory would make this method more expensive. However, it means that even if I set up my method to look like require.context('.', true, /^\.\/((?!node_modules).)*\.stories\.js$/) WebPack is still going to traverse my node_modules directories but won't match any internal *.stories.js files.
This becomes an issue when we use Lerna to install all the packages' depenencies via lerna bootstrap. Since by default that command will install ALL dependencies, including devDependencies for stuff like automated tests, an individual node_modules directory for a component could be quite large. So as we are adding more and more components, we have ran into a memory issue with running Storybook when components have all of their dependencies installed.
Our initial band-aid solution, was to restrict Lerna from install devDependencies by using lerna bootstrap -- --production --no-optional however this makes us unable to run tests. To run tests, we then have to install all dependencies... which means we can't run Storybook until we clean up the node_modules.
Our current solution is to use a fs type of library/package that allows us to traverse the directory tree with more specificity, and manually ignore node_modules when scanning deep directories. This allows us to still nest components within parent directories for better organization of similar components, and still allows Storybook to automatically find new *.stories.js files. So now our story discovery and Storybook config looks like:
const path = require('path');
const directoryTree = require('directory-tree');
let isPopulatedDir = (item) => item.type === 'directory' && item.children.length > 0;
let isStoryFile = (item) => item.type === 'file' && /\.stories\.js$/.test(item.name);
function parseChildren(children, response) {
for(var i = 0; i < children.length; i++) {
let child = children[i];
if(child.name === 'node_modules') continue;
if (isPopulatedDir(child)) {
parseChildren(child.children, response);
} else if(isStoryFile(child)) {
response.push(child.path);
}
}
return response;
}
function getStories() {
const tree = directoryTree("./packages/vue/components"),
storyPaths = [];
tree.children.forEach(item => {
if (isPopulatedDir(item)) {
storyPaths.push(...parseChildren(item.children, []));
}
});
return storyPaths;
}
module.exports = {
stories: getStories(),
webpackFinal: async (config) => {
config.node = {
fs: "empty"
};
config.resolve.modules = [
...(config.resolve.modules || []),
path.resolve('./'),
];
// Return the altered config
return config;
}
}
This solution works, it doesn't traverse any node_module directories, and allow us to dynamically find the *.stories.js files, no matter how their directory may be set up. But we can't help but feel like this is a problem that other people have had to of ran into, and maybe we are just overlooking a solution that Webpack already offers. So please, if you have had similar obstacles to overcome whose solution may work better for us we'd love to hear your approach or thoughts on our solution.

Generate i18n static HTML using Parcel bundler

I'm using Parceljs to bundle html and js. It works really well with less configuration.
Now, I'm facing i18n issue.
Google recommends using different URLs for each language version of a page.
https://support.google.com/webmasters/answer/182192
So, I want to generate language specific static html from one template like below.
.
├── dist
│ ├── ja
│ │ └── index.html
│ ├── app.c328ef1a.js
│ └── index.html
├── i18n
│ ├── default.json
│ └── ja.json
└── source
├── app.js
└── index.html
source/index.html
<html>
<body>
<h1>__TITLE__</h1>
<script src="/app.js"></script>
</body>
</html>
i18n/default.json
{
"__TITLE__": "Hello world!"
}
i18n/ja.json
{
"__TITLE__": "こんにちは 世界!"
}
Is there a way to deal with this issue using parceljs?
Or, should I write a code for prebuild?
Thank you.
Self answer:
I found a great answer here.
It mentions node-static-i18n package that generates i18n static HTML.
This tool isn't a plugin of parceljs, but it seems to be able to generate expected results.
Welcome yet another answer.

WebPack + WebExtensions/Chrome Extension - getBackground() not working

I'm developing a Firefox/Chrome Addon/Extension with the same codebase by utilizing the WebExtensions API and the web-extensions-browser polyfill (through webpack and RequireJS).
I noticed Firefox requires code to be unobfuscated and unminified when submitting a version, and thus had to install the unminify-webpack-plugin here.
The last hindering issue I have is that since webpack includes all the required files in one file (as it usually does), the functionality for browser.extension.getBackground() here doesn't work, as all my functions in my background.js are added to an anonymous module function.
Any suggestions on how I'd go about solving this?
Edit 1: Here's some more insight
My folder structure is as follows:
plugin/
├── wepback.config.js
├── manifest.json
├── package.json
├── package-lock.json
├── node_modules/
├── *dist/
├── img/
│ ├── icon.png
│ ├── ... etc
├── src/
│ ├── background/
│ │ ├── background.js
│ │ └── background.html
│ └── popup/
│ ├── popup.js
│ └── popup.html
Where my config is as follows:
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
var UnminifiedWebpackPlugin = require('unminified-webpack-plugin');
module.exports = {
entry: {
background: './src/background/background.js',
popup: './src/popup/popup.js'
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name]/[name].min.js"
},
plugins: [
new CopyPlugin([
{ from: './src/background/background.html', to: 'background/background.html'},
{ from: './src/popup/popup.html', to: 'popup/popup.html'},
{ from: './src/popup/popup.css', to: 'popup/popup.css'},
{ from: './manifest.json', to: 'manifest.json'},
{ from: './img', to: 'img/[name].[ext]'},
]),
new UnminifiedWebpackPlugin()
],
};
Edit 2:
Found the following boiler plate which looks promising. This does seem like an issue that, once solved, can just be reused - so I'll try it out soon and move my project over and test.
https://github.com/fstanis/webextensions-webpack-boilerplate
The best way to work around this is using the extension API's message system, with the sendMessage function and onMessage event - or the port system. See chrome's tutorial on message passing for more information.
Alternatively, you can access the window object directly in your background page - for example, with window.foo = 'bar'. Then getBackgroundPage() will work as expected. Directly mutating or accessing variables across contexts is slightly bad practice, and I'm guessing accessing variables through the window object may be as well, but I think it's probably fine as this is what getBackgroundPage() is intended for anyway.

PHP and Vue integration

Recently I've been involved in a Project, a PHP panel. It uses pure PHP and they have given me permission to access a folder to add my functionalities as an add-on to the existing panel.
The file structure is like so:
/
├── assets/
│ └── ...
├── config/
│ └── ...
├── test/
│ └── ...
.
.
.
├── MYAPP/
│ └── api/
│ │ ├── foo/
│ ├── index.html
│ └── ...
.
.
.
├── myApp.php
├── ...
myApp.php file has some requires to PHP files to load the theme and some scripts at the top and at the bottom.
I can require the index.html from MYAPP folder to load the main page of the app itself with all of the scripts and stylesheets working correctly as it is located in the root.
The URL now is “webpage.com/myApp.php”
Is it possible to create an SPA using the current file myApp.php with Vue and Vue-router like so?
“webpage.com/myApp.php/#/addCategory”
“webpage.com/myApp.php/#/editCategory”
…
Or should I make URL calls like this and load the content old fashion way?
“webpage.com/myApp.php? page=addCategory”
“webpage.com/myApp.php? page=editCategory”
-...
I have tried the vue spa template changing the base option with the vue-router but it didn't work.
What could be my options? Any ideas?

RequireJS - what should I set for the BaseUrl?

I'm having trouble understanding how to set the base URL for requirejs given the structure of my project.
The issue: Not all html files will be on the same folder level. The script file paths keep changing depending on the location of the html page.
What I've tried: I've scoured the API, but I just don't understand what the BaseURL should be to get the correct path for all pages. I've tested variations (../js/lib, /js/lib/, I tried not including it all in the main.js file) but this one below is the only one that seems to produce the correct result on certain files.
Main.js
requirejs.config({
baseUrl: '../js/lib',
paths: {
'jquery' : (document.addEventListener) ? ['vendor/jquery'] : ['vendor/jquery-1.9.1']
},
shim: {
'foundation/foundation': {
deps: ['jquery']
},
'foundation/foundation.alert': {
deps: ['jquery', 'foundation/foundation']
},
'vendor/slick.min': {
deps: [
'jquery',
'foundation',
'foundation/foundation.interchange'
],
exports: 'slick'
}
}
});
requirejs(['jquery'
, 'foundation/foundation'
]);
Folder Structure
Main Folder
│
│ Some Folder
│ ├── css
│ ├── js
│ │ ├── lib
│ │ │ ├── foundation
│ │ │ │ ├── foundation.alert.js
│ │ │ │ ├── ...(foundation component js files)
│ │ │ │ ├── foundation.js
│ │ │ ├── vendor
│ │ │ │ ├── jquery-1.9.1.js
│ │ │ │ ├── jquery.js
│ │ │ ├── foundation.min.js
│ │ │ ├── slick.min.js
│ │ │ └── slickModule.js
│ │ ├── main.js
│ │ └── require.js
│ ├── html
│ │ ├── components
│ │ │ ├── slider.html [All scripts throw 404: Main Folder/Some Folder/html/js/lib/vendor/file.js ]
│ │ ├── home.html [loads files as expected]
│ │ ├── second.html [loads files as expected]
│ │ ├── subfolder
│ │ │ └── random.html
│ ├── extra folder
│ │ └── index.html [All scripts throw 404: Main Folder/Some Folder/extra folder/js/lib/vendor/file.js ]
│ │
│ Another Folder
│ ├── index.html [All scripts throw 404]
/html/components/slider.html
When I try to call require this way, the slickModule's url is
"Main Folder/Some Folder/html/js/lib/slickModule.js" - note 'html' is added after the base url
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script data-main="../../js/main" src="../../js/require.js"></script>
<script>
require(['../js/main'], function () {
require(['slickModule']);
});
</script>
</head>
<body>
...
</body>
</html>
Could someone help me to see why this could be happening?
If it's even possible, what can I do to get the base URL to be consistent?
Summary
Don't require the same file twice in a row, especially if it's the file that changes your configuration options, especially if it uses relative paths.
Use a single application entry-point. If you can't start your application in a single place, it will be difficult (though not impossible) to use the data-main attribute.
Use the paths configuration option to point to files, not relative paths when you're including the module or setting up the config.
Single Entry Point
First of all, you're likely running into some issues with your data-main attribute since its behavior when used for multiple entry points is undocumented. As it says:
If you want to to do require() calls in the HTML page, then it is best to not use data-main. data-main is only intended for use when the page just has one main entry point, the data-main script. For pages that want to do inline require() calls, it is best to nest those inside a require() call for the configuration
Multiple requires
Secondly, you're using the data-main attribute to load your config which defines the behavior of the library (in other words, the require/requirejs function is customized), but then you use that customized tool to load the configuration again:
<script data-main="../../js/main" src="../../js/require.js"></script>
<script>
require(['../js/main'], function () {
require(['slickModule']);
});
</script>
I'm almost positive this introduces some strange behavior.
Use paths to avoid ../
Third, your baseUrl is automatically set to either the location of the HTML that loaded it, or the location of the data-main script. You can use this to your advantage by creating a single entry point (probably js/main), and then defining the paths configuration option to hide nested modules.
In other words, your application should never need to request ../ (or any variation thereof) because anything nested should be hidden by a paths entry like:
"paths": {
"slickModule": "lib/slickModule"
}
I know this answer doesn't specifically solve your problem, but I'm positive that one of these issues - when corrected - will solve your 404 problem.
I had this same issue in an ASP.NET MVC4 application, structured like so:
Main Folder
├── Scripts
│ ├── Libraries
│ │ ├── jquery
│ │ | ├── jquery-1.10.2.min.js
...
What I did was use my server side technology's method to determine the app's "root location". In my case, this is HttpRequest.ApplicationPath, which "gets the ASP.NET application's virtual application root path on the server." (source).
My requirejs setup looks like:
<script type="text/javascript">
var require = {
baseUrl: '#(Request.ApplicationPath)/Scripts',
paths: {
jquery: 'Libraries/jquery/jquery-1.10.2.min',
...
}
}
</script>
<script type="text/javascript" src="#Url.Content("~/Scripts/Libraries/require/require.js")"></script>
To summarize:
My base URL is the root application path plus the Scripts folder
Each path starts with the folder that is a child of Scripts
This forces requirejs to use an absolute path to the libraries instead of trying to figure out the relative ones from various directories.
Any scripts not specified in the paths configuration should also start with the folder that is a child of Scripts
You shouldn't need to use ../ anywhere in your configuration
Hope that helps, obviously you'll need to adjust this for whatever technology you're using.
Since you have html-files in different folders at different levels, setting your baseUrl as a relative path (i.e. ../lib/js) will work for some files, but for all, that's to be expected. You need to set an absolute path, from your root directory to your lib folder, e.g. if 'Main Folder' is your root, your baseUrl should be /Some Folder/js/lib/ or /Some Folder/js/lib. I hope that helps.

Categories

Resources