Browse Source

cypress tests on /structures ok

Olivier Massot 4 years ago
parent
commit
5838dcaec0

+ 4 - 0
.gitignore

@@ -89,3 +89,7 @@ sw.*
 # Vim swap files
 *.swp
 /.project
+
+# Cypress
+/cypress/screenshots
+/cypress/videos

+ 9 - 0
README.md

@@ -67,3 +67,12 @@ More information about the usage of this directory in [the documentation](https:
 This directory contains your Vuex store files. Creating a file in this directory automatically activates Vuex.
 
 More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/store).
+
+
+## Run tests
+
+To run end-to-end tests with [Cypress](https://docs.cypress.io/guides/):
+
+    yarn cypress
+
+

+ 13 - 1
cypress.json

@@ -1 +1,13 @@
-{}
+{
+  "baseUrl": "http://localhost:3004",
+  "fixturesFolder": "test/cypress/fixtures",
+  "integrationFolder": "test/cypress/integration",
+  "pluginsFile": "test/cypress/plugins/index.js",
+  "screenshotsFolder": "test/cypress/screenshots",
+  "supportFile": "test/cypress/support/index.js",
+  "videosFolder": "test/cypress/videos",
+  "env": {
+    "apiUrl": "http://nginx"
+  },
+  "watchForFileChanges": false
+}

+ 2 - 1
package.json

@@ -10,7 +10,8 @@
     "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
     "lint": "yarn lint:js",
     "test": "jest",
-    "cypress": "node_modules/.bin/cypress open"
+    "cypress": "node_modules/.bin/cypress open",
+    "cypress:silent": "node_modules/.bin/cypress run"
   },
   "dependencies": {
     "@fortawesome/fontawesome-svg-core": "^1.2.36",

+ 1 - 1
pages/structures/index.vue

@@ -225,7 +225,7 @@
                             </td>
                             <td class="py-1">
                               <span v-if="structure.streetAddress">{{ structure.streetAddress }}<br></span>
-                              <span v-if="structure.postalCode">{{ structure.postalCode }} </span>
+                              <span v-if="structure.postalCode" class="postalCode">{{ structure.postalCode }} </span>
                               {{ structure.addressCity }}
                             </td>
                           </tr>

+ 21 - 0
test/cypress/fixtures/structure-by-id.json

@@ -0,0 +1,21 @@
+[
+  {
+    "id": "498",
+    "name": "Orchestre d\u0027Harmonie de Cluses",
+    "logoId": "13043",
+    "website": "https:\/\/ohcluses.opentalent.fr",
+    "latitude": "46.06039",
+    "longitude": "6.580582",
+    "streetAddress": "16 B rue du Pr\u00e9 B\u00e9n\u00e9vix Place Claude Anthoine Salle Andr\u00e9 Favre",
+    "postalCode": "74300",
+    "addressCity": "CLUSES",
+    "telphone": null,
+    "email": "ohcluses@openassos.fr",
+    "facebook": "https:\/\/www.facebook.com\/orchestredharmoniede.cluses\/",
+    "twitter": "",
+    "instagram": null,
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny"
+  }
+]

+ 546 - 1
test/cypress/fixtures/structures.json

@@ -1,3 +1,548 @@
 [
-
+  {
+    "id": "5854",
+    "name": "CMF Rh\u00f4ne-Alpes",
+    "logoId": "13038",
+    "principalType": "REGIONAL_FEDERATION",
+    "website": "https:\/\/fmra.opentalent.fr",
+    "latitude": "45.527896881103516",
+    "longitude": "5.741861820220947",
+    "streetAddress": "Mairie de la Bridoire 510 route du Lac",
+    "postalCode": "73520",
+    "addressCity": "LA BRIDOIRE",
+    "country": null,
+    "practices": null,
+    "n1Id": "12097",
+    "n1Name": "CONF\u00c9D\u00c9RATION MUSICALE DE FRANCE",
+    "n2Id": null,
+    "n3Id": null,
+    "n4Id": null,
+    "n5Id": null,
+    "parents": "12097"
+  },
+  {
+    "id": "2289",
+    "name": "Union des F\u00e9d\u00e9rations Musicales de Haute-Savoie",
+    "logoId": "13039",
+    "principalType": "DEPARTEMENTAL_FEDERATION",
+    "website": "https:\/\/ufm74.opentalent.fr",
+    "latitude": "46.381401062012",
+    "longitude": "6.5108823776245",
+    "streetAddress": "13 avenue Jules Ferry",
+    "postalCode": "74200",
+    "addressCity": "THONON-LES-BAINS",
+    "country": null,
+    "practices": null,
+    "n1Id": "5854",
+    "n1Name": "CMF Rh\u00f4ne-Alpes",
+    "n2Id": "12097",
+    "n3Id": null,
+    "n4Id": null,
+    "n5Id": null,
+    "parents": "5854,12097"
+  },
+  {
+    "id": "1374",
+    "name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "logoId": "13040",
+    "principalType": "LOCAL_FEDERATION",
+    "website": "https:\/\/fmfaucigny.opentalent.fr",
+    "latitude": "46.06029510498",
+    "longitude": "6.5806193351746",
+    "streetAddress": "MAIRIE DE CLUSES HOTEL DE VILLE",
+    "postalCode": "74300",
+    "addressCity": "Cluses",
+    "country": null,
+    "practices": null,
+    "n1Id": "2289",
+    "n1Name": "Union des F\u00e9d\u00e9rations Musicales de Haute-Savoie",
+    "n2Id": "5854",
+    "n3Id": "12097",
+    "n4Id": null,
+    "n5Id": null,
+    "parents": "2289,5854,12097"
+  },
+  {
+    "id": "1893",
+    "name": "F\u00e9d\u00e9ration Musicale du Chablais",
+    "logoId": "13041",
+    "principalType": "LOCAL_FEDERATION",
+    "website": "https:\/\/fmchablais.opentalent.fr",
+    "latitude": "46.37556457519531",
+    "longitude": "6.527181148529053",
+    "streetAddress": "Batiment Ivomar ZAC du Larry",
+    "postalCode": "74200",
+    "addressCity": "MARIN",
+    "country": "France",
+    "practices": null,
+    "n1Id": "2289",
+    "n1Name": "Union des F\u00e9d\u00e9rations Musicales de Haute-Savoie",
+    "n2Id": "5854",
+    "n3Id": "12097",
+    "n4Id": null,
+    "n5Id": null,
+    "parents": "2289,5854,12097"
+  },
+  {
+    "id": "1849",
+    "name": "F\u00e9d\u00e9ration musicale du Genevois",
+    "logoId": "13042",
+    "principalType": "LOCAL_FEDERATION",
+    "website": "https:\/\/fmgenevois.opentalent.fr",
+    "latitude": "45.747020721436",
+    "longitude": "6.2935471534729",
+    "streetAddress": "8 rue Sainte Catherine",
+    "postalCode": "74600",
+    "addressCity": "ANNECY",
+    "country": "France",
+    "practices": null,
+    "n1Id": "2289",
+    "n1Name": "Union des F\u00e9d\u00e9rations Musicales de Haute-Savoie",
+    "n2Id": "5854",
+    "n3Id": "12097",
+    "n4Id": null,
+    "n5Id": null,
+    "parents": "2289,5854,12097"
+  },
+  {
+    "id": "498",
+    "name": "Orchestre d\u0027Harmonie de Cluses",
+    "logoId": "13043",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/ohcluses.opentalent.fr",
+    "latitude": "46.06039",
+    "longitude": "6.580582",
+    "streetAddress": "16 B rue du Pr\u00e9 B\u00e9n\u00e9vix Place Claude Anthoine Salle Andr\u00e9 Favre",
+    "postalCode": "74300",
+    "addressCity": "CLUSES",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "541",
+    "name": "Musique Municipale de Passy \u0027Echo de Warens\u0027",
+    "logoId": "13044",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/musique-passy.opentalent.fr",
+    "latitude": "45.92109680175781",
+    "longitude": "6.695181846618652",
+    "streetAddress": "14 Chemin de l\u0027\u00eele",
+    "postalCode": "74190",
+    "addressCity": "PASSY",
+    "country": null,
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "584",
+    "name": "Harmonie d\u0027Evian",
+    "logoId": null,
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/orchestre-harmonie-evian.opentalent.fr",
+    "latitude": "46.39456558227539",
+    "longitude": "6.582443714141846",
+    "streetAddress": "1 nouvelle route du stade",
+    "postalCode": "74500",
+    "addressCity": "EVIAN",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1893",
+    "n1Name": "F\u00e9d\u00e9ration Musicale du Chablais",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1893,2289,5854,12097"
+  },
+  {
+    "id": "885",
+    "name": "Harmonie Municipale de Machilly \/ Saint-Cergues",
+    "logoId": null,
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/harmonie-machilly-saint-cergues.opentalent.fr",
+    "latitude": "46.25160217285156",
+    "longitude": "6.331543922424316",
+    "streetAddress": "290 route des Voirons",
+    "postalCode": "74140",
+    "addressCity": "MACHILLY",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1893",
+    "n1Name": "F\u00e9d\u00e9ration Musicale du Chablais",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1893,2289,5854,12097"
+  },
+  {
+    "id": "842",
+    "name": "Orchestre d\u0027harmonie de La Clusaz",
+    "logoId": "13045",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/echo-des-aravis.opentalent.fr",
+    "latitude": "45.90581130981445",
+    "longitude": "6.421348571777344",
+    "streetAddress": "Espace Musique 41, Salon des Dames",
+    "postalCode": "74220",
+    "addressCity": "LA CLUSAZ",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1849",
+    "n1Name": "F\u00e9d\u00e9ration musicale du Genevois",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1849,2289,5854,12097"
+  },
+  {
+    "id": "928",
+    "name": "Orchestre d\u0027Harmonie de Sevrier",
+    "logoId": "13046",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/ohsevrier.opentalent.fr",
+    "latitude": "45.863983154297",
+    "longitude": "6.1415858268738",
+    "streetAddress": "8 rue Sainte Catherine",
+    "postalCode": "74600",
+    "addressCity": "ANNECY",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1849",
+    "n1Name": "F\u00e9d\u00e9ration musicale du Genevois",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1849,2289,5854,12097"
+  },
+  {
+    "id": "1065",
+    "name": "Orchestre d\u0027Harmonie Municipal de Marignier",
+    "logoId": "13048",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/ohm-marignier.opentalent.fr",
+    "latitude": "46.0908203125",
+    "longitude": "6.500844955444336",
+    "streetAddress": "SALLE JEAN BALLALOUD 17 RUE DU PATRONAGE",
+    "postalCode": "74970",
+    "addressCity": "MARIGNIER",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1199",
+    "name": "Harmonie Municipale de Samo\u00ebns",
+    "logoId": "13049",
+    "principalType": "ARTISTIC_PRACTICE_EDUCATION",
+    "website": "https:\/\/hm-samoens.opentalent.fr",
+    "latitude": "46.084044",
+    "longitude": "6.728173",
+    "streetAddress": "C\/ Sarah GUILLOT 200 route de Mathonex La Combe",
+    "postalCode": "74340",
+    "addressCity": "SAMOENS",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1462",
+    "name": "L\u0027Echo du Lac B\u00e9nit",
+    "logoId": "151967",
+    "principalType": "ARTISTIC_PRACTICE_EDUCATION",
+    "website": "https:\/\/musique-mtsaxonnex.opentalent.fr",
+    "latitude": "46.0538444519043",
+    "longitude": "6.484353542327881",
+    "streetAddress": "Mairie route de l\u0027\u00e9glise",
+    "postalCode": "74130",
+    "addressCity": "MONT-SAXONNEX",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1548",
+    "name": "Orchestre d\u0027Harmonie de Chamonix Mont-Blanc",
+    "logoId": "13051",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/chamonixmusique.opentalent.fr",
+    "latitude": "45.9780387878418",
+    "longitude": "6.922300338745117",
+    "streetAddress": "242.LE PLAGNOLET",
+    "postalCode": "74400",
+    "addressCity": "CHAMONIX MONT-BLANC",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1505",
+    "name": "Harmonie Municipale de Saint-Jeoire",
+    "logoId": "13052",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/harmonie-saint-jeoire.opentalent.fr",
+    "latitude": "46.137715",
+    "longitude": "6.457955",
+    "streetAddress": "Mairie 156 rue du Fau\u00e7igny",
+    "postalCode": "74490",
+    "addressCity": "SAINT-JEOIRE EN FAUCIGNY",
+    "country": null,
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1591",
+    "name": "Harmonie municipale des Houches l\u0027 \u00e9cho des glaciers",
+    "logoId": "13053",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/musique-leshouches.opentalent.fr",
+    "latitude": "45.89430618286133",
+    "longitude": "6.803390026092529",
+    "streetAddress": "72 rte de la griaz",
+    "postalCode": "74310",
+    "addressCity": "LES HOUCHES",
+    "country": null,
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1634",
+    "name": "Harmonie Municipale de Saint Gervais",
+    "logoId": null,
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/harmonie-stgervais74.opentalent.fr",
+    "latitude": "45.89208984375",
+    "longitude": "6.711752414703369",
+    "streetAddress": "Mairie de Saint Gervais 50 Avenue du Mont d\u0027Arbois",
+    "postalCode": "74170",
+    "addressCity": "SAINT GERVAIS",
+    "country": null,
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1677",
+    "name": "Orchestre d\u0027harmonie   Meg\u00e8ve",
+    "logoId": "170018",
+    "principalType": "ARTISTIC_PRACTICE_EDUCATION",
+    "website": "https:\/\/ohmegeve.opentalent.fr",
+    "latitude": "45.856876373291",
+    "longitude": "6.6177501678467",
+    "streetAddress": "Maison des fr\u00e8res 23 quai du Glapet",
+    "postalCode": "74120",
+    "addressCity": "MEGEVE",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1720",
+    "name": "Harmonie de Mieussy",
+    "logoId": "13054",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/harmoniemieussy.opentalent.fr",
+    "latitude": "46.133934020996094",
+    "longitude": "6.5243239402771",
+    "streetAddress": "Chef-Lieu Mairie",
+    "postalCode": "74440",
+    "addressCity": "MIEUSSY",
+    "country": null,
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1763",
+    "name": "Harmonie Municipale Reignier-Esery",
+    "logoId": "13055",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/harmonie-reignier.opentalent.fr",
+    "latitude": "46.13705062866211",
+    "longitude": "6.2681145668029785",
+    "streetAddress": "197 Grande Rue Mairie de Reignier",
+    "postalCode": "74930",
+    "addressCity": "REIGNIER",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1806",
+    "name": "Estudiantina d\u0027Annecy",
+    "logoId": null,
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/estudiantina-annecy.opentalent.fr",
+    "latitude": "45.89717102050781",
+    "longitude": "6.125161170959473",
+    "streetAddress": "5, all\u00e9e du Tertre Chateauvieux",
+    "postalCode": "74600",
+    "addressCity": "SEYNOD",
+    "country": "France",
+    "practices": "PLUCKED_ORCHESTRA",
+    "n1Id": "1849",
+    "n1Name": "F\u00e9d\u00e9ration musicale du Genevois",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1849,2289,5854,12097"
+  },
+  {
+    "id": "1938",
+    "name": "HARMONIE MUNICIPALE DE SALLANCHES",
+    "logoId": "13056",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/sallanchesharmonie.opentalent.fr",
+    "latitude": "45.93632125854492",
+    "longitude": "6.629683494567871",
+    "streetAddress": "quai de l hotel de ville mairie",
+    "postalCode": "74700",
+    "addressCity": "SALLANCHES",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "1981",
+    "name": "Ecole de Musique des Aravis",
+    "logoId": null,
+    "principalType": "ARTISTIC_PRACTICE_EDUCATION",
+    "website": "https:\/\/aravismusique.opentalent.fr",
+    "latitude": "45.90442657470703",
+    "longitude": "6.42335319519043",
+    "streetAddress": "41, Salon des Dames Espace Musique",
+    "postalCode": "74220",
+    "addressCity": "LA CLUSAZ",
+    "country": "France",
+    "practices": "ORCHESTRA_CLASS",
+    "n1Id": "1849",
+    "n1Name": "F\u00e9d\u00e9ration musicale du Genevois",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1849,2289,5854,12097"
+  },
+  {
+    "id": "2024",
+    "name": "Harmonie Municipale d\u0027Ar\u00e2ches La Frasse",
+    "logoId": "13057",
+    "principalType": "ARTISTIC_PRACTICE_ONLY",
+    "website": "https:\/\/harmonie-araches-lafrasse.opentalent.fr",
+    "latitude": "46.02651596069336",
+    "longitude": "6.636077880859375",
+    "streetAddress": "213 route des cyclamens",
+    "postalCode": "74300",
+    "addressCity": "Ar\u00e2ches-la-Frasse",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  },
+  {
+    "id": "2072",
+    "name": "Harmonie Municipale de Marnaz",
+    "logoId": "13058",
+    "principalType": "ARTISTIC_PRACTICE_EDUCATION",
+    "website": "https:\/\/harmoniedemarnaz.opentalent.fr",
+    "latitude": "46.060596466064",
+    "longitude": "6.5268602371216",
+    "streetAddress": "65, rue Antoine de Saint Exup\u00e9ry",
+    "postalCode": "74460",
+    "addressCity": "MARNAZ",
+    "country": "France",
+    "practices": "HARMONY_ORCHESTRA",
+    "n1Id": "1374",
+    "n1Name": "F\u00e9d\u00e9ration des Musiques du Faucigny",
+    "n2Id": "2289",
+    "n3Id": "5854",
+    "n4Id": "12097",
+    "n5Id": null,
+    "parents": "1374,2289,5854,12097"
+  }
 ]

+ 185 - 2
test/cypress/integration/structures/index.spec.js

@@ -1,8 +1,191 @@
 
-describe('Show page', () => {
-  it('Visits the /structures page', () => {
+describe('Test the /structures page', () => {
+  beforeEach(() => {
     cy.visit('/structures')
+  })
+
+  it('Map, filters, and all results shall display by default', () => {
+    // leaflet map is visible and was correctly instanciated
+    cy.get('#map', { timeout: 8000 })
+      .should('be.visible')
+      .children('.leaflet-pane')
+
+    // an input exists with the label 'Quoi ?'
+    cy.getByLabel('input', 'Quoi ?')
+      .should('be.enabled')
+
+    // an input exists with the label 'Où ?'
+    cy.getByLabel('input', 'Où ?')
+      .should('be.enabled')
+
+    // a select exists with the label 'Type'
+    cy.getByLabel('input', 'Type')
+      .should('be.enabled')
+
+    // a select exists with the label 'Département'
+    cy.getByLabel('input', 'Département')
+      .should('be.enabled')
+
+    // a select exists with the label 'Fédération'
+    cy.getByLabel('input', 'Fédération')
+      .should('be.enabled')
 
+    // a select exists with the label 'Distance'
+    cy.getByLabel('input', 'Distance')
+      .should('be.enabled')
+
+    // there are results displayed
+    cy.get('.structure-card').should('exist')
+  })
+
+  it('If view is set on list mode, map shall be hidden', () => {
     cy.contains('Liste').click()
+
+    cy.get('#map', { timeout: 8000 })
+      .should('not.be.visible')
+
+    // results should still be visible
+    cy.get('.structure-card')
+      .should('have.length', 8)
+  })
+
+  it('When list view is activated, displayed results and filters shall stay the same', () => {
+    cy.getByLabel('input', 'Quoi ?').type('some long text that will hopefully match no result')
+    cy.contains('Rechercher').click()
+
+    cy.get('.structure-card')
+      .should('have.length', 0)
+
+    cy.contains('Liste').click()
+
+    cy.get('.structure-card')
+      .should('have.length', 0)
+  })
+
+  it('The results shall be paginated', () => {
+    // 8 results are displayed (a whole page)
+    cy.get('.structure-card')
+      .should('have.length', 8)
+
+    // 8 pages are displayed in the pagination bar (max authorized)
+    cy.get('.v-pagination')
+      .find('button.v-pagination__item')
+      .should('have.length.gte', 2)
+
+    cy.getByLabel('input', 'Quoi ?').type('some long text that will hopefully match no result')
+    cy.contains('Rechercher').click()
+
+    cy.get('.v-pagination')
+      .find('button.v-pagination__item')
+      .should('have.length', 1)
+  })
+
+  it('The number of results shall match the current search', () => {
+    cy.get('.results-count')
+      .invoke('text')
+      .should('match', /\d+ Résultats/)
+
+    cy.getByLabel('input', 'Quoi ?').type('some long text that will hopefully match no result')
+    cy.contains('Rechercher').click()
+
+    cy.get('.results-count').should('have.text', '0 Résultats')
+  })
+
+  it('The results shall be filtered according to the text filter', () => {
+    cy.getByLabel('input', 'Quoi ?').type('tambour')
+    cy.contains('Rechercher').click()
+
+    cy.get('.structure-card .title')
+      .invoke('text')
+      .then((s) => { return s.toLowerCase() })
+      .should('match', /.*tambour.*/m)
+  })
+
+  it('The results shall be filtered according to the location filter', () => {
+    cy.getByLabel('input:visible', 'Où ?').type('strasbourg')
+    cy.get('.v-list-item div').contains(/Strasbourg \(\d{5}\)/).click()
+    cy.contains('Rechercher').click()
+
+    // we check that there is not a postal code that is not like '67xxx'
+    // note: we're forced to make this negative assertion, because some structures
+    //       could have no postal code displayed. So we consider the test passed if
+    //       there is no postal code that would'nt have a 6 in first position
+    //       and a 7 in second position
+    cy.get('.structure-card .postalCode')
+      .should('not.match', /.*[012345789]\d{4}.*/)
+      .and('not.match', /.*\d[012345789]\d{3}.*/)
+  })
+
+  it('The results shall be filtered according to the practice filter', () => {
+    cy.getByLabel('.v-select__selections', 'Type').click()
+    cy.get('.v-list-item').contains('Big band').click()
+    cy.contains('Rechercher').click()
+
+    cy.get('.structure-card').should('contain.text', 'Big band')
+  })
+
+  it('The results shall be filtered according to the department filter', () => {
+    cy.getByLabel('.v-select__selections', 'Département').click()
+    cy.get('.v-list-item').contains('01 - Ain').click()
+    cy.contains('Rechercher').click()
+
+    // we check that there is not a postal code that is not like '01xxx' (@see note from location filter test)
+    cy.get('.structure-card .postalCode')
+      .should('not.match', /.*[123456789]\d{4}.*/)
+      .and('not.match', /.*\d[023456789]\d{3}.*/)
+  })
+
+  it('The results shall be filtered according to the federation filter', () => {
+    cy.getByLabel('.v-select__selections', 'Fédération').click()
+    cy.get('.v-list-item').contains('CONFÉDÉRATION MUSICALE DE FRANCE').click()
+    cy.contains('Rechercher').click()
+
+    // I don't know how to test this...
+    cy.get('.structure-card').should('have.length.gte', 1)
+  })
+
+  it('The results shall be filtered according to the map bounds', () => {
+    // dragging the map there should lead in the middle of the atlantic, where we have no clients (for now)
+    cy.get('#map', { timeout: 6000 })
+      .dragMapFromCenter({ xMoveFactor: 2, yMoveFactor: 0 })
+
+    cy.get('.structure-card')
+      .should('have.length', 0)
+  })
+
+  it('Reinitialize shall clear each filter field, display all results, and reset map bounds (in both map and list view)', () => {
+    cy.getByLabel('input', 'Quoi ?').type('some long text that will hopefully match no result')
+    cy.getByLabel('input:visible', 'Où ?').type('vesoul')
+    cy.get('.v-list-item div').contains(/Vesoul \(\d{5}\)/).click()
+    cy.getByLabel('.v-select__selections', 'Type').click()
+    cy.get('.v-list-item').contains('Big band').click()
+    cy.getByLabel('.v-select__selections', 'Département').click()
+    cy.get('.v-list-item').contains('01 - Ain').click()
+    cy.getByLabel('.v-select__selections', 'Fédération').click()
+    cy.get('.v-list-item').contains('CONFÉDÉRATION MUSICALE DE FRANCE').click()
+    cy.getByLabel('.v-select__selections', 'Distance').click()
+    cy.get('.v-list-item').contains('10km').click()
+
+    // no structure will match these criterias
+    cy.contains('Rechercher').click()
+    cy.get('.structure-card')
+      .should('have.length', 0)
+
+    cy.contains('Réinitialiser').click()
+
+    cy.getByLabel('input', 'Quoi ?').should('not.have.value', 'foo')
+    cy.getByLabel('input:visible', 'Où ?').should('not.have.value', 'bar')
+    cy.getByLabel('input', 'Type').should('not.have.value', 'Big band')
+    cy.getByLabel('input', 'Département').should('not.have.value', '01 - Ain')
+    cy.getByLabel('input', 'Fédération').should('not.have.value', 'CONFÉDÉRATION MUSICALE DE FRANCE')
+    cy.getByLabel('input', 'Distance').should('not.have.value', '10km')
+
+    cy.get('.structure-card')
+      .should('have.length.gt', 0)
+  })
+
+  it('The see-more button of a structure card shall lead to the details page of the structure', () => {
+    cy.get('.structure-card').contains('Voir plus').parent().click()
+    cy.url().should('match', /.*structures\/\d+/)
   })
 })

+ 29 - 19
test/cypress/plugins/index.js

@@ -1,22 +1,32 @@
-/// <reference types="cypress" />
-// ***********************************************************
-// This example plugins/index.js can be used to load plugins
-//
-// You can change the location of this file or turn off loading
-// the plugins file with the 'pluginsFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/plugins-guide
-// ***********************************************************
 
-// This function is called when a project is opened or re-opened (e.g. due to
-// the project's config changing)
+let server // static reference to the mock server, so we can close and re-assign on 2nd call
 
-/**
- * @type {Cypress.PluginConfig}
- */
-// eslint-disable-next-line no-unused-vars
-module.exports = (on, config) => {
-  // `on` is used to hook into various events Cypress emits
-  // `config` is the resolved Cypress config
+module.exports = (on, _config) => {
+  on('task', {
+    mockServer ({ interceptUrl, fixture }) {
+      const fs = require('fs')
+      const http = require('http')
+      const { URL } = require('url')
+
+      if (server) {
+        // close any previous instance
+        server.close()
+      }
+
+      const url = new URL(interceptUrl)
+      server = http.createServer((req, res) => {
+        if (req.url === url.pathname) {
+          const data = fs.readFileSync(`./cypress/fixtures/${fixture}`)
+          res.end(data)
+        } else {
+          res.end()
+        }
+      })
+
+      server.listen(url.port)
+      console.log(`listening at port ${url.port}`)
+
+      return null
+    }
+  })
 }

+ 25 - 25
test/cypress/support/commands.js

@@ -1,25 +1,25 @@
-// ***********************************************
-// This example commands.js shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add('login', (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+/**
+ * Get an element by its label
+ *
+ * ex: cy.getByLabel('input', 'Search')
+ */
+Cypress.Commands.add(
+  'getByLabel',
+  (selector, label) => {
+    return cy.contains('label', label)
+      .parent()
+      .find(selector)
+  })
+
+/**
+ *
+ */
+Cypress.Commands.add(
+  'containing',
+  {
+    prevSubject: true
+  },
+  (subject, rx) => {
+    return subject.filter(() => { return rx.test(Cypress.$(this).text()) })
+  }
+)

+ 2 - 0
test/cypress/support/index.js

@@ -15,6 +15,8 @@
 
 // Import commands.js using ES2015 syntax:
 import './commands'
+import './leaflet'
+import './vuetify'
 
 // Alternatively you can use CommonJS syntax:
 // require('./commands')

+ 78 - 0
test/cypress/support/leaflet.js

@@ -0,0 +1,78 @@
+
+/**
+ * Allows dragging a Leaflet map by the given amounts. A factor of 1 means the map
+ * will be dragged the whole width of the map canvas in X direction and the whole
+ * height of the map canvas in Y direction.
+ *
+ * ex: cy.get('#map-canvas').dragMapFromCenter({ xMoveFactor: 0.25, yMoveFactor: -0.5 })
+ */
+Cypress.Commands.add(
+  'dragMapFromCenter',
+  { prevSubject: 'element' },
+  (element, { xMoveFactor, yMoveFactor }) => {
+    // Get the raw HTML element from jQuery wrapper
+    const canvas = element.get(0)
+    const rect = canvas.getBoundingClientRect()
+    const center = {
+      x: rect.left + rect.width / 2,
+      y: rect.top + rect.height / 2
+    }
+
+    // Start dragging from the center of the map
+    cy.log('mousedown', {
+      clientX: center.x,
+      clientY: center.y
+    })
+    canvas.dispatchEvent(
+      new MouseEvent('mousedown', {
+        clientX: center.x,
+        clientY: center.y
+      })
+    )
+
+    // Let Leaflet know the mouse has started to move. The diff between
+    // mousedown and mousemove event needs to be large enough so that Leaflet
+    // will really think the mouse is moving and not that it was a click where
+    // the mouse moved just a tiny amount.
+    cy.log('mousemove', {
+      clientX: center.x,
+      clientY: center.y + 5
+    })
+    canvas.dispatchEvent(
+      new MouseEvent('mousemove', {
+        clientX: center.x,
+        clientY: center.y + 5,
+        bubbles: true
+      })
+    )
+
+    // After Leaflet knows mouse is moving, we move the mouse as depicted by the options.
+    cy.log('mousemove', {
+      clientX: center.x + rect.width * xMoveFactor,
+      clientY: center.y + rect.height * yMoveFactor
+    })
+    canvas.dispatchEvent(
+      new MouseEvent('mousemove', {
+        clientX: center.x + rect.width * xMoveFactor,
+        clientY: center.y + rect.height * yMoveFactor,
+        bubbles: true
+      })
+    )
+
+    // Now when we "release" the mouse, Leaflet will fire a "dragend" event and
+    // the search should register that the drag has stopped and run callbacks.
+    cy.log('mouseup', {
+      clientX: center.x + rect.width * xMoveFactor,
+      clientY: center.y + rect.height * yMoveFactor
+    })
+    requestAnimationFrame(() => {
+      canvas.dispatchEvent(
+        new MouseEvent('mouseup', {
+          clientX: center.x + rect.width * xMoveFactor,
+          clientY: center.y + rect.height * yMoveFactor,
+          bubbles: true
+        })
+      )
+    })
+  }
+)

+ 0 - 0
test/cypress/support/vuetify.js


+ 9 - 0
test/unit/pages/structures/index.spec.js

@@ -0,0 +1,9 @@
+import Vuetify from 'vuetify'
+
+let vuetify
+beforeEach(() => {
+  vuetify = new Vuetify()
+})
+
+describe('pages/structures/index.vue', () => {
+})

+ 0 - 24
test/unit/pages/structures_adherentes/index.spec.js

@@ -1,24 +0,0 @@
-import Vuetify from 'vuetify'
-
-let vuetify
-beforeEach(() => {
-  vuetify = new Vuetify()
-})
-
-describe('pages/structures_adherentes/index', () => {
-  it('map, filters, and all results shall display by default', async () => {})
-  it('if list view is activated, map shall be hidden', async () => {})
-  it('when list view is activated, displayed results and filters shall stay the same', async () => {})
-  it('results shall be paginated', async () => {})
-  it('pagination shall be updated depending on the number of results', async () => {})
-  it('number of results shall match the current search', async () => {})
-  it('results shall be filtered according to the text filter', async () => {})
-  it('results shall be filtered according to the location filter', async () => {})
-  it('results shall be filtered according to the practice filter', async () => {})
-  it('results shall be filtered according to the department filter', async () => {})
-  it('results shall be filtered according to the federation filter', async () => {})
-  it('results shall be filtered according to the map bounds', async () => {})
-  it('if location is set, results shall be filtered according to the distance filter', async () => {})
-  it('reinitialize shall clear each filter field, display all results, and reset map bounds (in both map and list view)', async () => {})
-  it('the see-more button of a structure card shall lead to the details page of the structure', async () => {})
-})