I am trying to build a cypress BDD framework. I've think I've created the feature and step definition file correctly. When I run the the test with npx cypress run --spec cypress/integration/examples/shoppingCart.feature --headed --browser chrome, I get the following result here in this video , the vid is about 20sec long.
I wasn't sure what to think so I did another video that was a process of elimination and looking at the BDD set up. I'm still unsure (this one is about 8 mins long).
I will add the feature file, step definition file and error message.
I am totally puzzled.
Error message
`1) End to End shopping cart
User can purchase items and have them delivered to shipping address:
Error: Step implementation missing for: I am on the Ecommerce page
at Context.resolveAndRunStepDefinition (http://localhost:54824/__cypress/tests?p=cypress/integration/examples/shoppingCart.feature:12277:11)
at Context.eval (http://localhost:54824/__cypress/tests?p=cypress/integration/examples/shoppingCart.feature:11603:35)
`
Feature file
Scenario: User can purchase items and have them delivered to shipping address
Given I am on the Ecommerce page
When I add the mobile handsets to the shopping cart
And I verify the total price of shopping cart
Then I select the checkout button
When I will select my shipping location
And I agree to the terms and conditions checkbox
When I select the Purchase button
Then I will see an alert stating my order was successful, plus an ETA delivery
Step Definition file
/// <reference types="Cypress" />
import { Given,When,Then,And } from "cypress-cucumber-preprocessor/steps";
import Homepage from "../../../support/pageObjects/Homepage";
import orderSummaryPage from "../../../support/pageObjects/orderSummaryPage";
import completeOrderPage from "../../../support/pageObjects/completeOrderPage";
const homepage = new Homepage()
const StartCheckout = new orderSummaryPage()
const CompleteOrder = new completeOrderPage()
Given ( 'I am on the Ecommerce page', () => {
cy.visit(Cypress.env('url')+"/angularpractice/")
})
When('I add the mobile handsets to the shopping cart',function () {
homepage.getShopTab().click()
this.data.mobileHandset.forEach(function(element) {// this custom commad will add items to your cart
cy.AddToCart(element)
});
StartCheckout.getBasketCheckoutButton().click()
} )//end of step
And('I verify the total price of shopping cart',() => {
//calculate shopping cart here
let sum=0
CompleteOrder.getProductCost().each(($e1, index, $list) =>{
const unitCost=$e1.text()
let res= unitCost.split(" ")
res= res[1].trim()
sum=Number(sum)+Number(res)
}).then(function()
{
cy.log(sum)
})
CompleteOrder.getBasketTotalCost().then(function(element)
{
const shopCartTotal=element.text()
var res= shopCartTotal.split(" ")
var total= res[1].trim()
expect(Number(total)).to.equal(sum)
})
} )//end of step
Then('I select the checkout button',() => {
StartCheckout.getStartCheckoutButton().click()
} )//end of step
When('I will select my shipping location',() => {
CompleteOrder.getShippingCountry().type('United Kingdom')
CompleteOrder.getShippingCountryConfirm().click()
} )//end of step
And('I agree to the terms and conditions checkbox',()=> {
CompleteOrder.getTermsConditionsCheckbox().click({force: true})
})//end of step
When('I select the Purchase button',()=> {
CompleteOrder.getPurchaseButton().click()
})
Then('I will see an alert stating my order was successful, plus an ETA delivery',()=> {
CompleteOrder.getPurchaseAlert().then(function(element){
const actualText= element.text()
expect(actualText.includes('Success')).to.be.true
})
})
I'm sure I even created the BDD framework in the right place.
Update:
I was just asked about the non global step definitions in my package.json (I only copied from the 'script' section onwards).
Taking a quick look I don't even see it.
"scripts": {
"open": "cypress open",
"scripts": "cypress run",
"headTest": "cypress run --headed ",
"chromeTest": "cypress run --browser chrome",
"firefoxTest": "cypress run --browser firefox",
"edgeTest": "cypress run --browser edge",
"testDashboard": "cypress run --record --key 1642c226-ca7f-49c3-b513-da4ee9222ca8 --parallel",
"clean:reports": "rm -R -f cypress/reports && mkdir cypress/reports && mkdir cypress/reports/mochareports",
"pretest": "npm run clean:reports",
"combine-reports": "mochawesome-merge ./cypress/reports/mocha/*.json > cypress/reports/mochareports/report.json",
"generate-report": "marge cypress/reports/mochareports/report.json -f report -o cypress/reports/mochareports",
"posttest": "npm run combine-reports && npm run generate-report",
"test": "npm run scripts || npm run posttest"
},
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"cypress": "^7.4.0",
"cypress-cucumber-preprocessor": "^4.1.3"
},
"dependencies": {
"cypress-multi-reporters": "^1.5.0",
"mocha": "^9.0.0",
"mochawesome": "^6.2.2",
"mochawesome-merge": "^4.2.0",
"mochawesome-report-generator": "^5.2.0",
"start-server-and-test": "^1.12.5"
}
}
Add the stepDefinitions option to the configuration,
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true,
"stepDefinitions": "cypress/integration/examples/BDD"
},
I set up your files and debugged through the source code.
Where should the step files be?
Basically, in loader.js this line
const stepDefinitionsToRequire = getStepDefinitionsPaths(filePath)
.map((sdPath) => `require('${sdPath}')`);
returns an empty array with your setup.
Digging into getStepDefinitionsPaths, and ignoring common steps for the moment, this line
let nonGlobalPath = getStepDefinitionPathsFrom(filePath);
is responsible for deciding where the steps files come from (filePath is the feature file full path).
and getStepDefinitionPathsFrom.js is just
return filePath.replace(path.extname(filePath), "")
which just removes the extension from
.../cypress/integration/examples/BDD/shoppingCart.feature
to give
.../cypress/integration/examples/BDD/shoppingCart
Then on this line nonGlobalPath is turned into a glob pattern to get all files of type .js, .ts, or .tsx
const nonGlobalPattern = `${nonGlobalPath}/**/*.+(js|ts|tsx)`;
which gives
.../cypress/integration/examples/BDD/shoppingCart/**/*.+(js|ts|tsx)
Conclusion: the step files must be in a folder with the same name as the feature file (in your case cypress/integration/examples/BDD/shoppingCart/) - except if you modify the commonPath setting (see below).
The step definition files can be named anything, as long as they have the correct extension. All files in that folder get searched for step definitions.
There is no need to move files up into the integration folder.
Fix #1
Create a new folder cypress/integration/examples/BDD/shoppingCart/ and move shoppingCartStepDef.js into it.
Config setting
stepDefinitions by itself has no effect on the steps location, but clearly it should from the documentation. This looks like a bug introduced by some change.
nonGlobalStepBaseDir affects the common steps path (which contains steps used across many features, e.g login), but not the path specific to the shoppingCart feature. Again, a bug due to the above problem.
commonPath seems to work as long as it points directly to the step definitions. The glob pattern **/*.+(js|ts|tsx) usage also has a bug - the pattern omits a trailing / which means the ** part (indicating any subfolder) is ineffective (See the difference between line 28 and the preceding line 26)
Fix #2
Set the commonPath config option to the folder containing the step definitions
"commonPath": "cypress/integration/examples/BDD/"
and you tests will work.
I was able to resolve this issue by doing the following:
I raised a ticket with the Developer as I noticed a NUMBER of people were all experiencing the same issue. The developer found they had a bug, fixed it and released a new version.
I had another issue after the new release and was able to fix that by:
I created a new folder under BDD called shopping cart. so it integrations/BDD/shoppingCart
Then I added the following to the package.json
},
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": false,
"stepDefinitions": "cypress/integration/BDD"
},
I think these changes will help. From your error I can tell is that the Feature file is not able to find your step definitions.
Change the name of the integration/examples to integration. Because of what I see from the cypress pre-processor plugins page, the tests are being searched under cypress/integration.
Again referring to the cypress pre-processor plugins page, the recommended way of writing a step definition file is that the steps definitions are searched from a directory with the same name as your .feature file.
So in your case, your .feature file is at cypress/integration/BDD/shoppingCart.feature. Now create a folder by the same name as the feature file inside the BDD folder cypress/integration/BDD/shoppingCart and inside that place your step definitions file there.
According to TheBrainFamily/cypress-cucumber-preprocessor/issues/596, use a folder matching the feature file
If the feature file is unable to read the .js script file then try to add the following in the package.json file.
When you define correct folder hierarchy then it will be able to detect and run the the script in the test runner of cypress. Like i have new folder with name "Drayxchange" so i added it like this below:
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": false,
"stepDefinitions": "cypress/integration/Drayxchange"
},
Related
I'm using Cypress for frontend testing and I defined a task in cypress.config file.
setupNodeEvents(on) {
on('task', {
downloads: downloadspath => {
return fs.readdirSync(downloadspath);
},
deleteFiles: directory => {
const files = fs.readdirSync(directory);
if (files.length === 0) {
return 0;
}
for (const file of files) {
fs.unlinkSync(path.join(directory, file));
}
return 0;
},
});
},
And when I use it in my tests, it gives an error like this:
There's no explanation so, I don't know how to fix this error.
cy.task does a simple work, it just deletes all files in the cypress/downloads folder.
Generally, if the task throws an error it shows up in the Cypress log. You may get more info if you open devtools and click on the Cypress log entry.
Specifically, fs.unlinkSync(path.join(directory, file)) is probably failing because there is a sub-directory in the directory, see Node.js fs.unlinkSync() Method
The fs.unlinkSync() method is used to synchronously remove a file or symbolic link from the filesystem. This function does not work on directories, therefore it is recommended to use fs.rmdir() to remove a directory.
Since you are deleting cypress/downloads in the test, be aware Cypress does that for you
Cypress Configuration - Downloads
trashAssetsBeforeRuns (default: true)
Whether Cypress will trash assets within the downloadsFolder, screenshotsFolder, and videosFolder before tests run with cypress run.
I want Cypress to execute custom scripts before and after running the specs suite.
The before:run and after:run APIs look perfect for that.
But the same snippet that works perfectly in before:run doesn’t seem to work in after:run:
module.exports = {
e2e: {
setupNodeEvents(on, config) {
on("before:run", details => {
console.log("Before run:")
exec("npm run cal", {}, handleExecOutput)
})
on("after:run", results => {
console.log("After run:")
exec("npm run cal", {}, handleExecOutput)
})
},
},
};
The cal script is defined in package.json as simply calling the native cal command, as a minimal test.
This is logging "Before run" and the calendar (not exactly together) before running the specs, and only "After run" after running the specs. However, if I change npm run cal to simply cal, the command is executed in both cases.
I’ve tried it with and without promises, with yarn and npm, always the same result. What am I missing?
Is there a good solution on how to include third party pre compiled binaries like imagemagick into an electron app? there are node.js modules but they are all wrappers or native binding to the system wide installed libraries. I wonder if it's possible to bundle precompiled binaries within the distribution.
Here's another method, tested with Mac and Windows so far. Requires 'app-root-dir' package, doesn't require adding anything manually to node_modules dir.
Put your files under resources/$os/, where $os is either "mac", "linux", or "win". The build process will copy files from those directories as per build target OS.
Put extraFiles option in your build configs as follows:
package.json
"build": {
"extraFiles": [
{
"from": "resources/${os}",
"to": "Resources/bin",
"filter": ["**/*"]
}
],
Use something like this to determine the current platform.
get-platform.js
import { platform } from 'os';
export default () => {
switch (platform()) {
case 'aix':
case 'freebsd':
case 'linux':
case 'openbsd':
case 'android':
return 'linux';
case 'darwin':
case 'sunos':
return 'mac';
case 'win32':
return 'win';
}
};
Call the executable from your app depending on env and OS. Here I am assuming built versions are in production mode and source versions in other modes, but you can create your own calling logic.
import { join as joinPath, dirname } from 'path';
import { exec } from 'child_process';
import appRootDir from 'app-root-dir';
import env from './env';
import getPlatform from './get-platform';
const execPath = (env.name === 'production') ?
joinPath(dirname(appRootDir.get()), 'bin'):
joinPath(appRootDir.get(), 'resources', getPlatform());
const cmd = `${joinPath(execPath, 'my-executable')}`;
exec(cmd, (err, stdout, stderr) => {
// do things
});
I think I was using electron-builder as base, the env file generation comes with it. Basically it's just a JSON config file.
See UPDATE below (this method isn't ideal now).
I did find a solution to this, but I have no idea if this is considered best practice. I couldn't find any good documentation for including 3rd party precompiled binaries, so I just fiddled with it until it finally worked with my ffmpeg binary. Here's what I did (starting with the electron quick start, node.js v6):
Mac OS X method
From the app directory I ran the following commands in Terminal to include the ffmpeg binary as a module:
mkdir node_modules/ffmpeg
cp /usr/local/bin/ffmpeg node_modules/ffmpeg/
cd node_modules/.bin
ln -s ../ffmpeg/ffmpeg ffmpeg
(replace /usr/local/bin/ffmpeg with your current binary path, download it from here) Placing the link allowed electron-packager to include the binary I saved to node_modules/ffmpeg/.
Then to get the bundled app path (so that I could use an absolute path for my binary... relative paths didn't seem to work no matter what I did) I installed the npm package app-root-dir by running the following command:
npm i -S app-root-dir
Now that I had the root app directory, I just append the subfolder for my binary and spawned from there. This is the code that I placed in renderer.js:.
var appRootDir = require('app-root-dir').get();
var ffmpegpath=appRootDir+'/node_modules/ffmpeg/ffmpeg';
console.log(ffmpegpath);
const
spawn = require( 'child_process' ).spawn,
ffmpeg = spawn( ffmpegpath, ['-i',clips_input[0]]); //add whatever switches you need here
ffmpeg.stdout.on( 'data', data => {
console.log( `stdout: ${data}` );
});
ffmpeg.stderr.on( 'data', data => {
console.log( `stderr: ${data}` );
});
Windows Method
Open your electron base folder (electron-quick-start is the default name), then go into the node_modules folder. Create a folder there called ffmpeg, and copy your static binary into this directory. Note: it must be the static version of your binary, for ffmpeg I grabbed the latest Windows build here.
To get the bundled app path (so that I could use an absolute path for my binary... relative paths didn't seem to work no matter what I did) I installed the npm package app-root-dir by running the following command from a command prompt in my app directory:
npm i -S app-root-dir
Within your node_modules folder, navigate to the .bin subfolder. You need to create a couple of text files here to tell node to include the binary exe file you just copied. Use your favorite text editor and create two files, one named ffmpeg with the following contents:
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../ffmpeg/ffmpeg" "$#"
ret=$?
else
node "$basedir/../ffmpeg/ffmpeg" "$#"
ret=$?
fi
exit $ret
And the the second text file, named ffmpeg.cmd:
#IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\ffmpeg\ffmpeg" %*
) ELSE (
#SETLOCAL
#SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\ffmpeg\ffmpeg" %*
)
Next you can run ffmpeg in your Windows electron distribution (in renderer.js) as follows (I'm using the app-root-dir node module as well). Note the quotes added to the binary path, if your app is installed to a directory with spaces (eg C:\Program Files\YourApp) it won't work without these.
var appRootDir = require('app-root-dir').get();
var ffmpegpath = appRootDir + '\\node_modules\\ffmpeg\\ffmpeg';
const
spawn = require( 'child_process' ).spawn;
var ffmpeg = spawn( 'cmd.exe', ['/c', '"'+ffmpegpath+ '"', '-i', clips_input[0]]); //add whatever switches you need here, test on command line first
ffmpeg.stdout.on( 'data', data => {
console.log( `stdout: ${data}` );
});
ffmpeg.stderr.on( 'data', data => {
console.log( `stderr: ${data}` );
});
UPDATE: Unified Simple Method
Well, as time as rolled on and Node has updated, this method is no longer the easiest way to include precompiled binaries. It still works, but when npm install is run the binary folders under node_modules will be deleted and have to be replaced again. The below method works for Node v12.
This new method obviates the need to symlink, and works similarly for Mac and Windows. Relative paths seem to work now.
You will still need appRootDir: npm i -S app-root-dir
Create a folder under your app's root directory named bin and place your precompiled static binaries here, I'm using ffmpeg as an example.
Use the following code in your renderer script:
const appRootDir = require('app-root-dir').get();
const ffmpegpath = appRootDir + '/bin/ffmpeg';
const spawn = require( 'child_process' ).spawn;
const child = spawn( ffmpegpath, ['-i', inputfile, 'out.mp4']); //add whatever switches you need here, test on command line first
child.stdout.on( 'data', data => {
console.log( `stdout: ${data}` );
});
child.stderr.on( 'data', data => {
console.log( `stderr: ${data}` );
});
The above answers helped me figure out how it could done but there is a much efficient way to distribute binary files.
Taking cues from tsuriga's answer, here is my code:
Note: replace or add OS path as required.
Update - 4 Dec 2020
This answer has been updated. Find the previous code to the bottom of this answer.
Download the needed packages
yarn add electron-root-path electron-is-packaged
# or
npm i electron-root-path electron-is-packaged
Create a directory ./resources/mac/bin
Place you binaries inside this folder
Create a file ./app/binaries.js and paste the following code:
import path from 'path';
import { rootPath as root } from 'electron-root-path';
import { isPackaged } from 'electron-is-packaged';
import { getPlatform } from './getPlatform';
const IS_PROD = process.env.NODE_ENV === 'production';
const binariesPath =
IS_PROD && isPackaged // the path to a bundled electron app.
? path.join(root, './Contents', './Resources', './bin')
: path.join(root, './build', getPlatform(), './bin');
export const execPath = path.resolve(
path.join(binariesPath, './exec-file-name')
);
Create a file ./app/get-platform.js and paste the following code:
'use strict';
import { platform } from 'os';
export default () => {
switch (platform()) {
case 'aix':
case 'freebsd':
case 'linux':
case 'openbsd':
case 'android':
return 'linux';
case 'darwin':
case 'sunos':
return 'mac';
case 'win32':
return 'win';
}
};
Add these lines inside the ./package.json file:
"build": {
....
"extraFiles": [
{
"from": "resources/mac/bin",
"to": "Resources/bin",
"filter": [
"**/*"
]
}
],
....
},
import binary as:
import { execPath } from './binaries';
#your program code:
var command = spawn(execPath, arg, {});
Why this is better?
The above answers require an additional package called app-root-dir
tsuriga's answer doesn't handle the (env=production) build or the pre-packed versions properly. He/she has only taken care of development and post-packaged versions.
Previous answer
Avoid using electron.remote as it is getting depreciated
app.getAppPath might throw errors in the main process.
./app/binaries.js
'use strict';
import path from 'path';
import { remote } from 'electron';
import getPlatform from './get-platform';
const IS_PROD = process.env.NODE_ENV === 'production';
const root = process.cwd();
const { isPackaged, getAppPath } = remote.app;
const binariesPath =
IS_PROD && isPackaged
? path.join(path.dirname(getAppPath()), '..', './Resources', './bin')
: path.join(root, './resources', getPlatform(), './bin');
export const execPath = path.resolve(path.join(binariesPath, './exec-file-name'));
tl;dr:
yes you can! but it requires you to write your own self-contained addon which does not make any assumptions on system libraries. Moreover in some cases you have to make sure that your addon is compiled for the desired OS.
Lets break this question in several parts:
- Addons (Native modules):
Addons are dynamically linked shared objects.
In other words you can just write your own addon with no dependency on system wide libraries (e.g. by statically linking required modules) containing all the code you need.
You have to consider that such approach is OS-specific, meaning that you need to compile your addon for each OS that you want to support! (depending on what other libraries you may use)
- Native modules for electron:
The native Node modules are supported by Electron, but since Electron is using a different V8 version from official Node, you have to manually specify the location of Electron's headers when building native modules
This means that a native module which has been built against node headers must be rebuilt to be used inside electron. You can find how in electron docs.
- Bundle modules with electron app:
I suppose you want to have your app as a stand-alone executable without requiring users to install electron on their machines. If so, I can suggest using electron-packager.
following Ganesh answer's which was really a great help, in my case what was working in binaries.js (for a mac build - did not test for windows or linux) was:
"use strict";
import path from "path";
import { app } from "electron";
const IS_PROD = process.env.NODE_ENV === "production";
const root = process.cwd();
const { isPackaged } = app;
const binariesPath =
IS_PROD && isPackaged
? path.join(process.resourcesPath, "./bin")
: path.join(root, "./external");
export const execPath = path.join(binariesPath, "./my_exec_name");
Considering that my_exec_name was in the folder ./external/bin and copied in the app package in ./Resources/bin. I did not use the get_platforms.js script (not needed in my case). app.getAppPath() was generating a crash when the app was packaged.
Hope it can help.
Heavily based on Ganesh's answer, but simplified somewhat. Also I am using the Vue CLI Electron Builder Plugin so the config has to go in a slightly different place.
Create a resources directory. Place all your files in there.
Add this to vue.config.js:
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
...
"extraResources": [
{
"from": "resources",
"to": ".",
"filter": "**/*"
}
],
...
}
}
}
}
Create a file called resources.ts in your src folder, with these contents:
import path from 'path';
import { remote } from 'electron';
// Get the path that `extraResources` are sent to. This is `<app>/Resources`
// on macOS. remote.app.getAppPath() returns `<app>/Resources/app.asar` so
// we just get the parent directory. If the app is not packaged we just use
// `<current working directory>/resources`.
export const resourcesPath = remote.app.isPackaged ?
path.dirname(remote.app.getAppPath()) :
path.resolve('resources');
Note I haven't tested this on Windows/Linux but it should work assuming app.asar is in the resources directory on those platforms (I assume so).
Use it like this:
import { resourcesPath } from '../resources'; // Path to resources.ts
...
loadFromFile(resourcesPath + '/your_file');
I'm trying to get svelte material UI working with snowpack.
I have installed Snowpack and Snowpacks svelte template like so:
npm install --save-dev snowpack#next
npx create-snowpack-app xpapp --template #snowpack/app-template-svelte
This works, the sample svelte page shows up. Next I followed the Svelte Material UI instructions to "bundle this in your own code" as cited on the Usage chapter in the instructions here: https://github.com/hperrin/svelte-material-ui#usage
So I installed Sass and configured it in my snowpack.config.json file like this:
{
"extends": "#snowpack/app-scripts-svelte",
"scripts": {
"build:scss": "sass"
},
"devOptions": {},
"installOptions": {}
}
I followed the (very concise) instructions here: https://www.snowpack.dev/#sass
I've also added an empty src/theme/_smui-theme.scss file to my source files as the instructions say, and I installed the nessecary #smui components.
The problem is that I'm currently getting this error when starting the snowpack dev server:
> snowpack dev
Snowpack Dev Server (Beta)
NOTE: Still experimental, default behavior may change.
Starting up...
⠙ snowpack installing... #smui/icon-button, #smui/top-app-bar, svelte/internal
✘ /home/erik/Projects/svelte-xpapp/xpapp/node_modules/#smui/icon-button/_index.scss
Error: Unexpected character '#' (Note that you need plugins to import files that are not JavaScript)
at error (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:161:30)
at Module.error (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:15120:16)
at tryParse (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:15009:23)
at Module.setSource (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:15410:30)
at ModuleLoader.addModuleSource (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:17460:20)
at async ModuleLoader.fetchModule (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:17521:9)
at async /home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:17491:36
at async Promise.all (index 0)
at async ModuleLoader.fetchModule (/home/erik/Projects/svelte-xpapp/xpapp/node_modules/snowpack/node_modules/rollup/dist/shared/rollup.js:17522:9)
at async Promise.all (index 0)
It seems that the #import statements in Material UI's _index.scss aren't recognized. I figure Snowpack should interpret/transpile .scss files, but it doesn't seem to be doing that.
So I came across the same problem using Svite as well as Snowpack. I was able to use the bare implementation:
// component.svelte <script>
import Button, { Label } from '#smui/button/bare'
import '#smui/button/bare.css'
That's all that's required with Svite.
With Snowpack, I needed to add rollup-plugin-svelte and update snowpack.config.js
// snowpack.config.js
module.exports = {
// ...
installOptions: {
rollup: { plugins: [require('rollup-plugin-svelte')()] }
},
// ...
}
I got it working with these install options:
installOptions: {
rollup: {
plugins: [
require("rollup-plugin-svelte")({
include: ["./node_modules"],
}),
require("rollup-plugin-postcss")({
use: [
[
"sass",
{
includePaths: ["./src/theme", "./node_modules"],
},
],
],
}),
],
},
},
Unfortunately, you'll have to run npx snowpack dev --reload for changes to the theme to take effect.
This won't extract css into .css files.
I also got an error message with the Dialog component during a production build.
Here is a full example: https://github.com/LeanderG/svelte-smui
Minimal reproduction (in VS 15 Preview 2):
Create a new project using the "JavaScript -> Windows -> Universal -> Blank App (Universal Windows)" template.
Rename main.js to main.ts.
Add a tsconfig.json file to your project (see here for why).
Enter the following code in main.ts:
declare var foo: any;
foo();
Go to "Debug -> Windows -> Exception Settings" and check "JavaScript Runtime Exceptions".
Click the green "Run on Local Machine" button.
An error message appears:
Unable to activate Windows Store app [...]. The wwahost.exe process started, but the activation request failed with error 'Windows was unable to communicate with the target application. This usually indicates that the target application's process aborted. More information may be available in the Debug pane of the Output window (Debug->Window->Output)'.
Expected behavior: the IDE should break on foo();.
There is a work-around for VS 2015 Update 3 (s/o to #minestarks on GitHub):
I assume you're running in an English locale here, otherwise I don't think the workaround is applicable.
Close VS.
In an administrator command prompt:
cd %ProgramFiles(x86)%\msbuild\microsoft\visualstudio\v14.0\typescript
mkdir en
copy *.xaml en
copy TypeScript.Tasks.dll en\TypeScript.Tasks.resources.dll
Now open your UWP project again, the TS files should be visible and building when you build your project.
Make sure Typescript for VS2015 is installed, and try with other codes. I tried with following codes:
function buildName(firstName: string, lastName: string) {
return firstName + " " + lastName;
}
let result3 = buildName("Bob", "Adams");
Make sure your "tsconfig" is correct:
{
"compilerOptions":
{
"module": "commonjs",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true
},
"files": [
"main.ts"
]
}
Make sure your main.js and main.js.map files are generated correctly(show all files in solution explorer to see these two files):
main.js:
function buildName(firstName, lastName) {
return firstName + " " + lastName;
}
var result3 = buildName("Bob", "Adams");
//# sourceMappingURL=main.js.map
main.js.map:
{"version":3,"file":"main.js","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":"AAAC,mBAAmB,SAAiB,EAAE,QAAgB;IACnD,MAAM,CAAC,SAAS,GAAG,GAAG,GAAG,QAAQ,CAAC;AACtC,CAAC;AAED,IAAI,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC"}
And here is my basic demo project:TypescriptDemo