Skip to content

editorGlobals

editor

pipeline status coverage report

Laser Editor

The editor that will be used by end users.

[[TOC]]

CI Testsystem / Demo

Go to www.kyub.com to test the latest stable release of the editor.

Development

You need to have node js (major version 14 recommended) and npm (version 6.14 recommended) installed. When you install node js 14, it should come with npm 6.14 by default.

Use npm install to install all required modules (help here if it fails). Then, run npm start to start a webpack-dev-server on port 3000 for local development. Now you can open the program by typing "http://localhost:3000/" into the address bar of your browser.

You can trigger a production build (minified source code) by passing the option npx grunt start --production or setting the environment variable NODE_ENV=production.\ To statically serve the editor without webpack-dev-server, Use npx grunt build to create a dist folder (preferrably in production mode).\ (The local grunt is used explicitly since using the global grunt-cli leads to failing require calls on some systems when initializing the grunt pipeline)

Some projects (kyutils, svg-import, maker-format-import, website-api, website-frontend) have been moved to the gitlab npm registry. To use the new versions you need an personal access token and set the npm config registry for @laser-project scoped packages. Generate your token with read_api and read_registry here: https://gitlab.dev.kyub.io/-/profile/personal_access_tokens and set these config values

npm config set @laser-project:registry https://gitlab.dev.kyub.io/api/v4/packages/npm/

npm config set -- '//gitlab.dev.kyub.io/api/v4/packages/npm/:_authToken' <your token>

As the packages come precompiled there's no postinstall script anymore and npm8/node16 should finally work.

Specialized deployments

By passing --mode=truss to grunt start or setting the environment variable KYUB_TRUSS_MODE to true, the editor will be launched in truss mode, allowing to build using System 180 and Strawbees. The branch system180 is continuously deployed to system180.kyub.com.

By passing --mode=release to grunt start or setting the environment variable KYUB_RELEASE_MODE to true, the editor will be launched in release mode with a very reduced, but stable feature set. The develop branch is continuously deployed to kyub.com/editor/new in release mode. If you want to use the complete unfiltered menu, use kyub.com/editor/new/#configChain=default,moduleConfig.

By passing --mode=preRelease to grunt start or setting the environment variable KYUB_PRERELEASE_MODE to true, the editor will use the menu that will be the next release = reduced feature set and aiming to be stable.

Development (runtime) dependencies

The editor needs the CSG Server running in order to produce correct geometry results (else, a buggy fallback will be used). If you develop around assets, you also need the AssetDB in order to be able to perform the upload + import + query workflow.

  1. All servers are provided as Docker images. Make sure to install docker and login to the kyub registry by using docker login registry.dev.kyub.io (with your Gitlab user/password).
  2. The CSG Server is now automatically started with grunt start. You can run the CSG server manually with grunt startCsg, and stop it with grunt stopCsg
  3. If you need to test the website/asset integration, you should start website-api and website-frontend in their repository. The default configuration should correctly proxy requests to each server. Note that you need to open localhost:8080, as the editor is embedded/proxied by the website-frontend repo.

You can override which csg server is being used by the webpack-dev-server (when running grunt start), by specifying the CSG_SERVER environment variable.

Testing

You can define what CSG server to use by setting the environment variable CSG_SERVER. Per default, the tests will use http://localhost:3002 (use grunt startCsg to start it).

Unit tests

Testing can be done by running grunt test (or just TS_NODE_FILES=true grunt mochaTest for mocha). If you want to test in WebStorm, make sure the mocha template / config has these Extra Mocha Options: -r coffeescript/register -r ts-node/register -r require-yaml -r ./test/util/defineTestingEnvironment.coffee -r ./test/util/defineSelf.coffee.

Important: Make sure that the options are configured in this specific order. Since they partially depend on each other its quite likely, that the test will not run if they are specified differently.

To select all tests, use the file pattern ./test/unitTests/**/*.{coffee,ts}. Make sure the environment variable TS_NODE_FILES=true is set inside the configurations.

Integration Tests / Headless Tests

Run the integration tests with grunt integrationTest.

As font rendering differs on Linux/Windows/Mac, we use the screenshots created within the Docker image environment as a reference for all tests.

If you changed something in the Editor and now have to update reference files / screenshots, you can easily retrieve the current state by going to gitlab, going to the pipelines page and select the integrationTest job that produced the new image. When opening the job page, you'll find a "Download job artifacts" section on the right side (only for failed jobs!) where you can download a zip file with the currently created screenshots / SVG files. Replace and commit the new files, and the pipeline should work again. Make sure to add one tool interaction in the kyubscript which changes nothing on the screenshot because there is no delay after the last interaction.

You can debug the integration tests locally: - run the test from webstorm - set -timeout 120000 in the run configurations - set headless = false in IntegrationTestEnvironment._startBrowser(). - install graphicsmagick

Look at production editor logs

Go to kyub.com/logs (obtain credentials from us) and refer to README_LOGS.md.

Configuration

Configuration is stored as yml files in the config/ subfolder. Mutliple files can be used to build up the config, extending/overriding existing values. If you create a new file, you have to add it inside the Config.coffee as well (due to browserify reasons).

You can control the config in the browser by changing the URL hash:

  • https://.../#configChain=default,mySubConfig1,... controls what config files are loaded in what order. The default config file will always be loaded first
  • https://.../#key=value#key2.subkey=value2 allows specifying individual values that will override values from file.

If there are unsaved changes, we ask the user before leaving the page. This can be disabled with the URL hash #modelSave.promptBeforeDiscardingChanges=false. This is set to true in the release (i.e. deployed version) and set to false in the defaultConfig, so it does not interfere with auto reload during development.

Assets

If you change contents of the assetDB folder, you need to rebuild the index by either running npm install or directly executing grunt shell:buildFileSystemAssetDb.

HowTo: Use the deployed AssetDB (e. g. on alpha.kyub.io) for local development

Change the content of Gruntfile.ts as follows:

proxy: {
  # leave any other proxy route as is (e. g. for '/api/v1/csg')
  '/api': {
    target: 'https://alpha.kyub.io'
    auth: 'dev:lapland2016'
    secure: false
    headers: {
      host: 'alpha.kyub.io'
    }
  }
}

HowTo: Test out a new asset

  1. create a folder in the assetDb folder like: editor/assetDb//resources/import/makerFormat/
  2. run grunt grunt shell:importAllMakerAssetsInPlace
  3. Copy how the swivelCaster example asset is used in a menu item
  4. you should be able to place the asset with your newly created menu item

HowTo: Test code accessing the website-api

This describes how to mock the website-api responses when testing code that usually would send out requests. If you intend to test the returned values of any specific route, it is likely that your test is more suited to be placed in the website-api repository.

  1. Write your test as you usually would
  2. Add a MockAPIProvider class to your test file. This class needs to implement the execute method which returns an object with at least the status and response fields. Here is an example (if you don't need any of the passed request, response information, you can simply leave out these parameters): ts class MockAPIProvider extends RequestProvider { public execute( requestMethod: string, requestUrl: string, requestHeaders: Record<string, any>, requestData: string, responseType: string, ): Promise<{ status: number; response: Record<string, any>; }> { return Promise.resolve({ response: { _id: "000000000000000000000000" }, status: 200 }); } }
  3. Add the before hook to your test. In it, enable the MockXMLHttpRequest and mock specify that you want to mock the API route that will be called using an instance of the MockAPIProvider you just implemented. ts before(() => { MockXMLHttpRequest.enableMock(); MockXMLHttpRequest.addRequestProvider("/api/v1/yourRoute", new MockAPIProvider()); }); Note that you my also need to call the configureDefaultRequestProviders function of the MockXMLHttpRequest if you're using the CSG server for example. Ensure that this happens after you define the handler for your API request. As the mocked requests are checked sequentially for a match to your request, defining your handling after the default handling could result in some other handler catching and processing your request first.
  4. Add the after hook to your test in which you disable the MockXMLHttpRequest again. ts after(() => { MockXMLHttpRequest.disableMock(); });

Icons

In the editor, we use icons in the menu and as mouse cursors. The sources of the icons is located in an Illustrator file located at resources/icons/icons.ai. All icons can be exported to SVG from that file.

The mouse cursor icons are generated from these exported SVGs using imagemagick using this command

for i in resources/icons/*.svg; do
 nameWithoutExtension=${i%.svg}
 magick -density 2500 -background none "$i" \( +clone -background black -shadow 100x15+0+0 \) -background none -compose DstOver -flatten -resize 32x32 "$nameWithoutExtension.ico"
done

Fonts

The simpleEngravingFont.json used to create text as cutlines on the cutting plan is a typeface.js font and was generated from a regular font using the facetype.js website.

And more...

Refer to the Coding Guidelines for TypeScript and CoffeeScript guidelines.