Shopware 6: Cypress test - reset database failed - cypress

I try to cleanup my database with command cy.cleanUpPreviousState:
// mytest.cy.js
...
beforeEach(() => {
cy.cleanUpPreviousState()
})
...
the request was response with error:
CypressError
cy.request() failed trying to load:
http://my-route.dev.localhost:8005/cleanup
The app runs in docker container, using shyim/shopware-docker
Questions
What is wrong with my request/route?
Which controller has to take this request?

To find out what is wrong, have a log at the network tab request log.
Answering your second question: There is a special server spun up for this action. It is not a normal Shopware route.
See in the cypress.js - it is supposed to use psh.phar to clean-up when this URL is called.
const requestedUrl = request.url;
if (requestedUrl !== "/cleanup") {
response.end();
return;
}
return childProcess.exec(
`${PROJECT_ROOT}/psh.phar e2e:cleanup`,
[...]
server.listen(8005);
So things to check are:
Is that port forwarded to your docker container?
Are you using the development template and is psh.phar existing?

Related

Examples of integrating moleculer-io with moleculer-web using moleculer-runner instead of ServiceBroker?

I am having fun with using moleculer-runner instead of creating a ServiceBroker instance in a moleculer-web project I am working on. The Runner simplifies setting up services for moleculer-web, and all the services - including the api.service.js file - look and behave the same, using a module.exports = { blah } format.
I can cleanly define the REST endpoints in the api.service.js file, and create the connected functions in the appropriate service files. For example aliases: { 'GET sensors': 'sensors.list' } points to the list() action/function in sensors.service.js . It all works great using some dummy data in an array.
The next step is to get the service(s) to open up a socket and talk to a local program listening on an internal set address/port. The idea is to accept a REST call from the web, talk to a local program over a socket to get some data, then format and return the data back via REST to the client.
BUT When I want to use sockets with moleculer, I'm having trouble finding useful info and examples on integrating moleculer-io with a moleculer-runner-based setup. All the examples I find use the ServiceBroker model. I thought my Google-Fu was pretty good, but I'm at a loss as to where to look to next. Or, can i modify the ServiceBroker examples to work with moleculer-runner? Any insight or input is welcome.
If you want the following chain:
localhost:3000/sensor/list -> sensor.list() -> send message to local program:8071 -> get response -> send response as return message to the REST caller.
Then you need to add a socket io client to your sensor service (which has the list() action). Adding a client will allow it to communicate with "outside world" via sockets.
Check the image below. I think it has everything that you need.
As a skeleton I've used moleculer-demo project.
What I have:
API service api.service.js. That handles the HTTP requests and passes them to the sensor.service.js
The sensor.service.js will be responsible for communicating with remote socket.io server so it needs to have a socket.io client. Now, when the sensor.service.js service has started() I'm establishing a connection with a remote server located at port 8071. After this I can use this connection in my service actions to communicate with socket.io server. This is exactly what I'm doing in sensor.list action.
I've also created remote-server.service.js to mock your socket.io server. Despite being a moleculer service, the sensor.service.js communicates with it via socket.io protocol.
It doesn't matter if your services use (or not) socket.io. All the services are declared in the same way, i.e., module.exports = {}
Below is a working example with socket.io.
const { ServiceBroker } = require("moleculer");
const ApiGateway = require("moleculer-web");
const SocketIOService = require("moleculer-io");
const io = require("socket.io-client");
const IOService = {
name: "api",
// SocketIOService should be after moleculer-web
// Load the HTTP API Gateway to be able to reach "greeter" action via:
// http://localhost:3000/hello/greeter
mixins: [ApiGateway, SocketIOService]
};
const HelloService = {
name: "hello",
actions: {
greeter() {
return "Hello Via Socket";
}
}
};
const broker = new ServiceBroker();
broker.createService(IOService);
broker.createService(HelloService);
broker.start().then(async () => {
const socket = io("http://localhost:3000", {
reconnectionDelay: 300,
reconnectionDelayMax: 300
});
socket.on("connect", () => {
console.log("Connection with the Gateway established");
});
socket.emit("call", "hello.greeter", (error, res) => {
console.log(res);
});
});
To make it work with moleculer-runner just copy the service declarations into my-service.service.js. So for example, your api.service.js could look like:
// api.service.js
module.exports = {
name: "api",
// SocketIOService should be after moleculer-web
// Load the HTTP API Gateway to be able to reach "greeter" action via:
// http://localhost:3000/hello/greeter
mixins: [ApiGateway, SocketIOService]
}
and your greeter service:
// greeter.service.js
module.exports = {
name: "hello",
actions: {
greeter() {
return "Hello Via Socket";
}
}
}
And run npm run dev or moleculer-runner --repl --hot services

Directory path is incorrect when running from cypress test runner

When I login from normal browser the login is successful with the URL : http://neelesh.zapto.org:8084/EnrolMe/indHome.html
But when I run the script from Cypress the directory location is not appended and the new URL after login is formed as : http://neelesh.zapto.org:8084/__/indHome.html
I have tried setting cypress.json with
{
"chromeWebSecurity": false,
"modifyObstructiveCode" : false
}
I have tried on chrome/electron(head and headless).
Below is my code snippet:
describe('My First Test Suite', function() {
it('My First test case', function() {
cy.visit("http://neelesh.zapto.org:8084/EnrolMe")
cy.get("#login").click()
cy.get("input[value='Individual']").click()
cy.get("#username").type('1234567890')
cy.get("#pwd").type('0646')
Cypress.Cookies.debug(true)
cy.clearCookies()
cy.get("#login").click()
cy.wait(6000)
})
})
When I run the script from Cypress the directory location is not appended and the new URL after login is formed as : http://neelesh.zapto.org:8084/__/indHome.html
It should be redirected as : http://neelesh.zapto.org:8084/EnrolMe/indHome.html
Can anyone help me on this?
This sounds like an issue with "Frame Busting". There's a related discussion for Cypress GitHub Issue #992 which may lend some help.
Your application code may contain problematic frame busting code like the following:
if (window.top !== window.self) {
window.top.location.href = window.self.location.href;
}
You can get around this by changing your application code's reference to window.self from the Application Window to the Cypress Test Runner window (window.top).
Cypress emits a series of events as it runs in your browser. You can use the emitted window:before:load application event to ensure it's done before you attempt to login.
// cypress/support/index.js
Cypress.on('window:before:load', (win) => {
Object.defineProperty(win, 'self', {
get: () => {
return window.top
}
})
})

Turn off annoying mocha logs on Axios error

I am testing my application and I noticed a thing that is annoying me. So my code is below. I am trying to register a user that is existing in database and asserting a failure.
async function registerUserAgain() {
try {
const { status } = await http.post(registrationUrl, user);
assert.notStrictEqual(status, httpStatus.CREATED);
} catch({ code, response }) {
assert.strictEqual(response.status, httpStatus.CONFLICT);
}
}
describe('Testing registration scenarios', function () {
it('Duplicate user registration failure', registerUserAgain);
}
This code does exactly what I want. However when I look at the output
Request failed with status code 409
✓ Duplicate user registration failure
How to remove this first line from the output? Logs would be prettier and cleaner if mocha and axios would not log those things.
you can try the following command $ mocha --reporter min test or take a look at the other reporter options
This looks like some bug thing in mocha. Updating it to 5.2.0 solved the issue

How to capture the transactions while doing testing using Mocha

I am in the process of writing unit/behavioural tests using Mocha for a particular blockchain network use-case. Based on what I can see, these tests are not hitting the actual fabric, in other words, they seem to be running in some kind of a simulated environment. I don't get to see any of the transactions that took place as a part of the test. Can someone please tell me if it is somehow possible to capture the transactions that take place as part of the Mocha tests?
Initial portion of my code below:
describe('A Network', () => {
// In-memory card store for testing so cards are not persisted to the file system
const cardStore = require('composer-common').NetworkCardStoreManager.getCardStore( { type: 'composer-wallet-inmemory' } );
let adminConnection;
let businessNetworkConnection;
let businessNetworkDefinition;
let businessNetworkName;
let factory;
//let clock;
// Embedded connection used for local testing
const connectionProfile = {
name: 'hlfv1',
'x-type': 'hlfv1',
'version': '1.0.0'
};
before(async () => {
// Generate certificates for use with the embedded connection
const credentials = CertificateUtil.generate({ commonName: 'admin' });
// PeerAdmin identity used with the admin connection to deploy business networks
const deployerMetadata = {
version: 1,
userName: 'PeerAdmin',
roles: [ 'PeerAdmin', 'ChannelAdmin' ]
};
const deployerCard = new IdCard(deployerMetadata, connectionProfile);
console.log("line 63")
const deployerCardName = 'PeerAdmin';
deployerCard.setCredentials(credentials);
console.log("line 65")
// setup admin connection
adminConnection = new AdminConnection({ cardStore: cardStore });
console.log("line 69")
await adminConnection.importCard(deployerCardName, deployerCard);
console.log("line 70")
await adminConnection.connect(deployerCardName);
console.log("line 71")
});
Earlier, my connection profile was using the embedded mode, which I changed to hlfv1 after looking at the answer below. Now, I am getting the error: Error: the string "Failed to import identity. Error: Client.createUser parameter 'opts mspid' is required." was thrown, throw an Error :). This is coming from
await adminConnection.importCard(deployerCardName, deployerCard);. Can someone please tell me what needs to be changed. Any documentation/resource will be helpful.
Yes you can use a real Fabric. Which means you could interact with the created transactions using your test framework or indeed other means such as REST or Playground etc.
In Composer's own test setup, the option for testing against an hlfv1 Fabric environment is used in its setup (ie whether you want to use embedded, web or real Fabric) -> see https://github.com/hyperledger/composer/blob/master/packages/composer-tests-functional/systest/historian.js#L120
Setup is captured here
https://github.com/hyperledger/composer/blob/master/packages/composer-tests-functional/systest/testutil.js#L192
Example of setting up artifacts that you would need to setup to use a real Fabric here
https://github.com/hyperledger/composer/blob/master/packages/composer-tests-functional/systest/testutil.js#L247
Also see this blog for more guidelines -> https://medium.com/#mrsimonstone/debug-your-blockchain-business-network-using-hyperledger-composer-9bea20b49a74

React Router code split "randomly" fails at loading chunks

I am struggling with a issue with react-router + webpack code split + servicer worker (or cache).
Basically the issue is the following, the code split is working properly but from time to time I get error reports from customers at sentry.io such as:
"Dynamic page loading failed Error: Loading chunk 19 failed."
My react-router code is the following:
const errorLoading = (err) => {
console.error('Dynamic page loading failed', err);
};
export default (
<Route path="/" component={App}>
<IndexRoute
getComponent={(nextState, cb) => {
System.import('./containers/home/home')
.then((module) => { cb(null, module.default); })
.catch(errorLoading);
}}
/>
</Route>
);
For my ServiceWorker I use OfflinePlugin with the following configuration:
new OfflinePlugin({
cacheName: 'cache-name',
cacheMaps: [
{
match: function(requestUrl) {
return new URL('/', location);
},
requestTypes: ['navigate']
}
],
externals: [
'assets/images/logos/slider.png',
'assets/images/banners/banner-1-320.jpg',
'assets/images/banners/banner-1-480.jpg',
'assets/images/banners/banner-1-768.jpg',
'assets/images/banners/banner-1-1024.jpg',
'assets/images/banners/banner-1-1280.jpg',
'assets/images/banners/banner-1-1400.jpg'
],
responseStrategy: 'network-first', // One of my failed attempts to fix this issue
ServiceWorker: {
output: 'my-service-worker.js'
}
})
The issue is not browser related because I have reports from IE11, safari, chrome, etc.
Any clues on what I might be doing wrong or how can I fix this issue?
Edit 2: I ended using chunks with hashes, and doing a window.location.reload() inside errorLoading's catch(), so when the browser fails to load a chunk it will reload the window and fetch the new file.
<Route path="about"
getComponent={(location, callback) => {
System.import('./about')
.then(module => { callback(null, module.default) })
.catch(() => {
window.location.reload()
})
}}
/>
It happens to me too and I don't think I have a proper solution yet, but what I noticed is this usually happens when I deploy a new version of the app, the hashes of the chunks change, and when I try to navigate to another address (chunk) the old chunk doesn't exist (it seems as if it wasn't cached) and I get the error.
I managed to reproduce this by removing the service worker that caches stuff and deploying a new version (which I guess simulates a user without the service worker running?).
remove the service worker code
unregister the service worker in devtools
reload the page
deploy a new app version
navigate to another chunk (for instance from /home to /about)
In my case it appears as if the error occurs when the old files are not cached (hence not available any more) and the user doesn't reload the page to request new ones. Reloading 'fixes' the issue because the app has the new chunk names, which correctly load.
Something else I tried was to name the chunk files without their hashes, so instead of 3.something.js they were only 3.js. When I deployed a new version the chunks were obviously still there, but this is not a good solution because the files will be cached by the browser instead of being cached by the caching plugin.
Edit: same setup as you, using sw-precache-webpack-plugin.

Resources