Cypress JS custom commands not working in VUE CLI - vue.js

I'm trying to set up a custom command to add some session storage items in a project and it doesn't seem to be firing.
The command is as follows
Cypress.Commands.add("login", () => {
window.sessionStorage.setItem("token", "tokengoeshere");
window.sessionStorage.setItem("username", "phoenix");
cy.visit("http://localhost:8080");
});
I have added the file into cypress.json
"supportFile": "tests/e2e/support/index.js",
and the index.js looks like
// Import commands.js using ES2015 syntax:
import "./commands";
When the tests fire session storage is empty

Where are you calling that custom command?
You usually create custom commands in cypress/support/commands.js file and that makes those commands available under cy.
So paste this to your cypress/support/commands.js
Cypress.Commands.add("login", () => {
window.sessionStorage.setItem("token", "tokengoeshere");
window.sessionStorage.setItem("username", "phoenix");
cy.visit("http://localhost:8080");
});
and then call it with cy.login() from any test file. Those are usually in cypress/integration folder. For example in your case a file cypress/integration/myTestsWithCustomCommand.js:
describe("My tests using custom commands", () => {
it("1st test using custom command", () => {
cy.login();
// rest of your code test
});
});

Related

Fetch data from local JSON file with Nuxt Pinia

Is it possible to fetch a local .json. file using fetch()? I originally used the import method but the site's data doesn't get updated unless the page gets reloaded.
I tried doing this but it's not working:
stores/characters.ts
export const useCharactersStore = defineStore("characters", {
state: () => ({
characters: [],
}),
getters: {
getCharacters: (state) => {
return state.characters;
},
},
actions: {
fetchCharacters() {
fetch("../data.json")
.then((response) => response.json())
.then((data) => {
this.characters = data.characters;
});
},
},
});
app.vue
import { useCharactersStore } from "~/stores/characters";
const store = useCharactersStore();
onMounted(() => {
store.fetchCharacters();
});
Any help would be appreciated.
maybe a bit late but I have encountered the same problem migration from Nuxt 2 to Nuxt 3.
I'm certainly no expert on this, so if anyone finds a better way or if I'm totally wrong please let me know !
Whenever you import a json file in vue code they are imported as a module, that get's embedded within the code compilation on build (Vue Docs). Tu use json as a external file you need to place your json within the /public directory and use axios or fetch to load the file with a lifecyle hook.
This could be mounted() for options api or beforeMount()/onMounted() with composition api.
However some important annotations for this method.
If the json file you want to use in your app is not reactive, i.e. won't change, you should place this in the static folder of the nuxt app.
In your example you fetch '../data/...', this would imply the server knows the domain to look for. It can't call the route like this, you would have to give the full url if you put your json file in the static folder.
Set the baseUrl in the of your nuxt.config.ts, see docs for specifications.
Then you can access the static folder with your .env variables
--> $fe
Then in you data script you can access your json file
async getJson(some parameters){
const data = $fetch('your domain with the runtimeConfig composable').then((data)=>{ console.log(data)});
Sidenote you can also load the file from the server-side using fs.readFile
read more about this in this awesome post here

I want to persist/preserve login in all spec files instead of logging in again and again for every file

I want to persist/preserve login in all spec files instead of logging again and again for every file: I found solution for multiple tests is a single file but I need solution for multiple tests for multiple specs files
Save local storage across tests to avoid re-authentication
Set local storage in Cypress
https://www.npmjs.com/package/cypress-localstorage-commands
These are solutions for single file with multiple tests but I need solution for multiple files
The cypress-localstorage-commands package persists localStorage even between different tests files, this is its default behavior. As it describes in its documentation, it also provides a clearLocalStorageSnapshot command to clean the localStorage between test files if needed.
Note that you'll have to restore the localStorage in every test file using the cy.restoreLocalStorage() command:
describe("Tests file 1", () => {
beforeEach(() => {
cy.restoreLocalStorage();
});
afterEach(() => {
cy.saveLocalStorage();
});
});
describe("Tests file 2", () => {
beforeEach(() => {
cy.restoreLocalStorage();
});
afterEach(() => {
cy.saveLocalStorage();
});
});

Nuxt/Vuejs - How to create utils that have access to modules?

I am using asiox/vuejs to create a webpage. However I want to compartmentalize the code more. One example is I use axios to make requests to the backend, and the data in the response is commited into vuex.
this.$axios.get('events').then((response) => {
this.$store.commit('data/populate', response.data)
})
.catch((e) => {
console.error(e)
})
I want to write a util method for this, like this.$populate.events()
I have tried creating utils inside the plugins/ directory, but they dont have access to this.$axios or this.$store
Note that I have axios and vuex imported in nuxt.config.js
How can this be achieved?
If you need the function in the context, Vue instances and maybe even
in the Vuex store, you can use the inject function, which is the
second parameter of the plugins exported function.
Injecting content into Vue instances works similar to when doing this
in standard Vue apps. The $ will be prepended automatically to the
function.
Reference
export default ({ app, store }, inject) => {
inject("populate", () => {
app.$axios
.get("events")
.then(response => {
store.commit("data/populate", response.data);
})
.catch(e => {
console.error(e);
});
});
};
app variable is context property.
The root Vue instance options that includes all your plugins. For
example, when using axios, you can get access to $axios through
context.app.$axios.
Figured it out not 5 minutes after posting ...
Basically use this nuxt guide
And replace this with app in the method you'd like to move

Meteorjs test Meteor methods

I have the following simple Meteor Method that I want to test.
It inserts a given Object into my collection
Meteor.methods({
insertHelper(profile){
HelperCollection.insert(profile);
return true;
},
}
For Testing i use "dispatch:mocha-phantomjs"
My Test so far is the following:
describe('methods', () => {
it('can delete owned task', () => {
Meteor.call('insertHelper',{a: 1});
});
});
When running my tests I get the message " Error: Method 'insertHelper' not found [404]"
So how can I access my Meteor methods from my Test suite?
As discussed in the comments, we have to include the files where the Meteor methods are defined in order to test them :
import '/path/to/method/file.js';
or with require :
require('/path/to/methos/file.js');
EDIT
Meteor advises to use import instead of using require, if you can.

How to dynamically mock ES6 modules with SystemJS?

I have a single-page application written in ES6. The code in transpiled server-side into classic javascript by babelJs, then loaded by SystemJs.
Javascript present in my html file:
System.config({
baseURL: '/js',
meta: {
'/js/*': { format: 'cjs' }
}});
System.defaultJSExtensions = true;
System.import("index.js")
.catch(function (error) {
console.error(error)
});
index.js:
import f1 from 'file1';
import f2 from 'file2';
// code here ...
Everything works fine. index.js is loaded, and all import statements are correctly executed.
Now, I want to create some pages with mocked ES6 modules, for testing purpose. My goal is to display pages by replacing model classes (contained in ES6 modules) with other static test classes.
Let's say I have 3 files: real_model.js, fake_model.js and component.js. component.js import the real model (import Model from 'real_model';).
How can I replace the real model by the fake one (in the component) dynamically ?
It's been a while since this question was posted, but maybe this solution might still be of help to anyone else.
With SystemJS it is possible to create a module on-the-fly using System.newModule. Then you can use System.set to overwrite existing modules with the new one. In our tests we use the following helper function to mock existing modules:
function mockModule(name, value) {
const normalizedName = System.normalizeSync(name);
System.delete(normalizedName);
System.set(normalizedName, System.newModule(Object.assign({ default: value }, value)));
}
Then, e.g. inside the beforeEach callback, we assign the mock and then import the module to be tested using System.import:
let [component, fake_model] = [];
beforeEach(() => {
// define mock
fake_model = { foo: 'bar' };
// overwrite module with mock
mockModule('real_model', fake_model);
// delete and reimport module
System.delete(System.normalizeSync('component'));
return System.import('src/testing').then((m) => {
component = m.default;
}).catch(err => console.error(err));
});
// test your component here ...
A big advantage of this approach is that you don't need an additional mocking library and it works solely with SystemJS.