Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ jobs:

timeout-minutes: 60
runs-on: ${{ matrix.os }}
container:
image: cypress/browsers:22.12.0
options: --user 1001

steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v4

- name: Cypress run
uses: cypress-io/github-action@v4.2.0
uses: cypress-io/github-action@v6
with:
browser: ${{ matrix.browser }}
component: true
Expand Down
10,215 changes: 3,191 additions & 7,024 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@watts-lab/surveys",
"version": "1.18.1",
"version": "1.19.0",
"description": "",
"main": "dist/index.js",
"module": "dist/index.js",
Expand All @@ -26,25 +26,25 @@
"dist"
],
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"survey-react": "^1.9.52"
"react": "^18.3.1",
"react-dom": "^18.3.1",
"survey-react": "^1.12.17"
},
"devDependencies": {
"@babel/preset-react": "^7.18.6",
"@babel/preset-react": "^7.26.3",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-commonjs": "^22.0.2",
"@rollup/plugin-dynamic-import-vars": "^1.4.4",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^14.1.0",
"cypress": "^13.6.3",
"cypress-localstorage-commands": "^2.2.1",
"cypress": "^13.17.0",
"cypress-localstorage-commands": "^2.2.7",
"cypress-rollup-preprocessor": "^1.2.0",
"glob": "^8.1.0",
"rollup": "^2.79.1",
"rollup": "^2.79.2",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-terser": "^7.0.2",
"vite": "^3.1.4"
"vite": "^6.0.7"
}
}
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ import demographicsSha from "../surveys/demographics/sha.json";
import { default as demographicsScoreFunc } from "../surveys/demographics/demographics.score.js";
export const Demographics = SurveyFactory("demographics", demographicsJson, demographicsScoreFunc, demographicsSha);

import demographicsLongInternationalJson from "../surveys/demographicsLongInternational/demographicsLongInternational.json";
import demographicsLongInternationalSha from "../surveys/demographicsLongInternational/sha.json";
import { default as demographicsLongInternationalScoreFunc } from "../surveys/demographicsLongInternational/demographicsLongInternational.score.js";
export const DemographicsLongInternational = SurveyFactory("demographicsLongInternational", demographicsLongInternationalJson, demographicsLongInternationalScoreFunc, demographicsLongInternationalSha);

import demographicsShortUSJson from "../surveys/demographicsShortUS/demographicsShortUS.json";
import demographicsShortUSSha from "../surveys/demographicsShortUS/sha.json";
import { default as demographicsShortUSScoreFunc } from "../surveys/demographicsShortUS/demographicsShortUS.score.js";
Expand Down
41 changes: 41 additions & 0 deletions surveys/demographicsLongInternational/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Demographics Survey

## Survey purpose

Identify relatievly static attributes about an individual which are not likely to react to the stimulus in an experiment, but may be predictors of behavior.

The survey aims to ask questions that are appropriate to the respondent's home country, and so individuals resident in the US may (e.g.) see different survey questions than respondents from the UK.

### Screenshot

![Screenshot](screenshotGeneral.png)

# Question Sources

This survey aggregates questions from a number of sources:

- Impairment https://analysisfunction.civilservice.gov.uk/policy-store/impairment/

Using the [International Standard Classification of Education](https://en.wikipedia.org/wiki/International_Standard_Classification_of_Education)

Mappings from [UNESCO](http://uis.unesco.org/en/isced-mappings)

# Salary Range

The salary values and ranges were scraped on December 19th 2024 from [salaryexplorer.com](https://www.salaryexplorer.com/), and then rounded and bucketed into (If possible) 8 buckets. The values are in local currency.

## United Kingdom:

#### Education

Some inspiriation from https://www.lse.ac.uk/media-and-communications/assets/documents/research/preparing-for-a-digital-future/Questionnaire.pdf

#### Ethnicity

Source: https://analysisfunction.civilservice.gov.uk/policy-store/ethnicity-harmonised-standard/#questions-for-england

## United states

Questions from ANES: https://electionstudies.org/wp-content/uploads/2020/07/anes_pilot_2020ets_qnnaire.pdf

![Screenshot](screenshotUSA.png)
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import React from "react";
import { DemographicsLongInternational } from "../../src/index";
import { getContainerEl } from "cypress/react";
import ReactDom from "react-dom";

const dummy = {
set(response) {},
};

import demographicsData from "./demographicsLongInternational.json";

describe("Demographics", () => {
it("completes", () => {
cy.spy(dummy, "set").as("callback");
cy.mount(<DemographicsLongInternational onComplete={dummy.set} />);
cy.viewport("macbook-11");

cy.get(`[data-name="birth_year"] input`).click().type("1985");

cy.get(`[data-name="gender"] input[value="other"]`).click({ force: true });

cy.get(`[data-name="gender_other"] input`).click().type("Other gender");

cy.get(`[data-name="marital_status"] input`).click({ force: true });

cy.contains("Married or Domestic Partnership").click({ force: true });

cy.get(`[data-name="language_primary"] input`).click({ force: true });
cy.contains("French").click({ force: true });

cy.get(`[data-name="english_written"] input[value="4"]`).click({
force: true,
});

cy.get(`[data-name="english_spoken"] input[value="4"]`).click({
force: true,
});

cy.get(`[data-name="employment_status"] input[value="employed"]`).click({
force: true,
});

cy.get(
`[data-name="employment_industry"] input[value="Agriculture, Forestry, Fishing, and Hunting"]`
).click({
force: true,
});

cy.get(`[data-name="job_title"] input`).click().type("Survey Developer");

cy.get(`[data-name="country_reside"] input`).click({ force: true });
cy.contains("United States").click({ force: true });

cy.screenshot("./demographicsLongInternational/screenshotGeneral", {
overwrite: true,
});

cy.get(`input[type="button"][value="Next"]`).click({ force: true });

cy.get(`[data-name="education_US"] input[value="Doctorate"]`).click({
force: true,
});

cy.get(`[data-name="latin_US"] input[value="Yes"]`)
.next()
.click({ force: true });

cy.get(`[data-name="zipcode_US"] input`).click().type("52066");

cy.get(`[data-name="race_US"] input[value="White"]`)
.next()
.click({ force: true });
cy.get(`[data-name="race_US"] input[value="Other"]`)
.next()
.click({ force: true });

cy.get(`[data-name="income_US"] input[value="$50,000-$74,999"]`).click({
force: true,
});

cy.screenshot("./demographicsLongInternational/screenshotUSA", {
overwrite: true,
});

cy.get(`input[type="button"][value="Complete"]`).click({ force: true });

cy.get(".sv-body").should("not.exist");

cy.get("@callback").should("have.been.called");
cy.get("@callback").then((spy) => {
const spyCall = spy.getCall(-1).args[0];
console.log(spyCall);
expect(spyCall["result"]).to.be.empty;
expect(spyCall.responses.birth_year).to.have.string("1985");
});
});

it("Completes Other Countries", () => {
const country_list = demographicsData.pages[0].elements
.find((element) => element.name === "country_reside")
.choices.map((choice) => choice.value);

const countrySalaries = {};
for (const country of country_list) {
const country_code = country
.toLowerCase()
.replace(new RegExp(" ", "g"), "_")
.replace(",", "_")
.replace("(", "_")
.replace(")", "_");
let salaryFound = false;
for (let i = 1; i < demographicsData.pages.length; i++) {
const page = demographicsData.pages[i];
const incomeElement = page.elements.find(
(element) => element.name === `income_${country_code}`
);
if (incomeElement) {
const salary = incomeElement.choices[0];
countrySalaries[country_code] = salary;
salaryFound = true;
break;
}
}
if (!salaryFound) {
console.warn(`Salary data not found for country: ${country_code}`);
}
}

cy.spy(dummy, "set").as("callback");

country_list.slice(0, 10).forEach((country) => {
const country_code = country
.toLowerCase()
.replace(new RegExp(" ", "g"), "_")
.replace(",", "_")
.replace("(", "_")
.replace(")", "_");
console.log(country, country_code);

cy.mount(
<DemographicsLongInternational
storageName={country_code}
onComplete={dummy.set}
/>
);

// Proceed with filling out the survey
cy.viewport("macbook-11");
cy.get(`[data-name="birth_year"] input`).click().type("1985");
cy.get(`[data-name="gender"] input[value="other"]`).click({
force: true,
});
cy.get(`[data-name="gender_other"] input`).click().type("Other gender");
cy.get(`[data-name="marital_status"] input`).click({ force: true });
cy.contains("Married or Domestic Partnership").click({ force: true });
cy.get(`[data-name="language_primary"] input`).click({ force: true });
cy.contains("French").click({ force: true });
cy.get(`[data-name="english_written"] input[value="4"]`).click({
force: true,
});
cy.get(`[data-name="english_spoken"] input[value="4"]`).click({
force: true,
});
cy.get(`[data-name="employment_status"] input[value="employed"]`).click({
force: true,
});

cy.get(`[data-name="country_reside"] input`).click({ force: true });
cy.get(`[data-name="country_reside"]`)
.contains(country)
.click({ force: true });

cy.get(`input[type="button"][value="Next"]`).click({ force: true });
cy.get(
`[data-name="education_${country_code}"] input[value="Other (please specify)"]`
).click({
force: true,
});
cy.get(`[data-name="other_education_${country_code}"] input`)
.click()
.type("Survey Developer");
cy.get(`[data-name="zipcode_${country_code}"] input`)
.click()
.type("82919123");
cy.get(
`[data-name="ethnicity_${country_code}"] input[value="Middle Eastern or North African"]`
)
.next()
.click({ force: true });
cy.get(
`[data-name="income_${country_code}"] input[value="${countrySalaries[country_code]}"]`
).click({
force: true,
});
cy.get(`input[type="button"][value="Complete"]`).click({ force: true });

cy.wait(100);
});

cy.get(".sv-body").should("not.exist");
cy.get("@callback").should("have.been.called");
cy.get("@callback").then((spy) => {
const spyCall = spy.getCall(-1).args[0];
console.log(spyCall);
expect(spyCall["result"]).to.be.empty;
expect(spyCall.responses.birth_year).to.have.string("1985");
});
});
});
Loading
Loading