fcad-core-dragon 2.1.1 → 2.2.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +7 -7
- package/.gitlab-ci.yml +106 -0
- package/.prettierrc +11 -11
- package/.vscode/extensions.json +8 -8
- package/.vscode/settings.json +16 -16
- package/CHANGELOG +529 -520
- package/README.md +57 -57
- package/artifacts/playwright-report/index.html +85 -0
- package/documentation/.vitepress/config.js +114 -114
- package/documentation/api-examples.md +49 -49
- package/documentation/composants/app-base-button.md +58 -58
- package/documentation/composants/app-base-error-display.md +59 -59
- package/documentation/composants/app-base-popover.md +68 -68
- package/documentation/composants/app-comp-audio.md +75 -75
- package/documentation/composants/app-comp-branch-buttons.md +111 -111
- package/documentation/composants/app-comp-button-progress.md +53 -53
- package/documentation/composants/app-comp-carousel.md +53 -53
- package/documentation/composants/app-comp-container.md +53 -53
- package/documentation/composants/app-comp-input-checkbox-next.md +42 -42
- package/documentation/composants/app-comp-input-dropdown-next.md +34 -34
- package/documentation/composants/app-comp-input-radio-next.md +39 -39
- package/documentation/composants/app-comp-input-text-next.md +35 -35
- package/documentation/composants/app-comp-input-text-table-next.md +34 -34
- package/documentation/composants/app-comp-input-text-to-fill-dropdown-next.md +53 -53
- package/documentation/composants/app-comp-input-text-to-fill-next.md +31 -31
- package/documentation/composants/app-comp-jauge.md +31 -31
- package/documentation/composants/app-comp-menu-item.md +55 -55
- package/documentation/composants/app-comp-menu.md +29 -29
- package/documentation/composants/app-comp-navigation.md +41 -41
- package/documentation/composants/app-comp-note-call.md +53 -53
- package/documentation/composants/app-comp-note-credit.md +53 -53
- package/documentation/composants/app-comp-play-bar-next.md +53 -53
- package/documentation/composants/app-comp-pop-up-next.md +93 -93
- package/documentation/composants/app-comp-quiz-next.md +235 -235
- package/documentation/composants/app-comp-quiz-recall.md +53 -53
- package/documentation/composants/app-comp-svg-next.md +53 -53
- package/documentation/composants/app-comp-table-of-content.md +50 -50
- package/documentation/composants/app-comp-video-player.md +82 -82
- package/documentation/composants.md +46 -46
- package/documentation/composants_critiques/ModelPageComposant.md +53 -53
- package/documentation/composants_critiques/app-base-module.md +43 -43
- package/documentation/composants_critiques/app-base-page.md +48 -48
- package/documentation/composants_critiques/app-base.md +311 -311
- package/documentation/composants_critiques/main.md +15 -15
- package/documentation/demarrage.md +50 -50
- package/documentation/deploiement.md +57 -57
- package/documentation/index.md +33 -33
- package/documentation/markdown-examples.md +85 -85
- package/documentation/public/vite.svg +14 -14
- package/documentation/public/vuejs.svg +1 -1
- package/documentation/public/vuetify.svg +5 -5
- package/eslint.config.js +60 -60
- package/package.json +69 -59
- package/playwright/index.html +12 -0
- package/playwright/index.js +21 -0
- package/playwright-ct.config.js +95 -0
- package/src/$locales/en.json +157 -157
- package/src/$locales/fr.json +120 -120
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +1171 -1169
- package/src/components/AppBaseButton.vue +90 -95
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +1639 -1634
- package/src/components/AppBasePage.vue +862 -866
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppBaseSkeleton.vue +66 -66
- package/src/components/AppCompAudio.vue +261 -256
- package/src/components/AppCompBranchButtons.vue +508 -508
- package/src/components/AppCompButtonProgress.vue +137 -132
- package/src/components/AppCompCarousel.vue +342 -336
- package/src/components/AppCompContainer.vue +29 -29
- package/src/components/AppCompInputCheckBoxNx.vue +326 -323
- package/src/components/AppCompInputDropdownNx.vue +302 -299
- package/src/components/AppCompInputRadioNx.vue +288 -284
- package/src/components/AppCompInputTextNx.vue +154 -153
- package/src/components/AppCompInputTextTableNx.vue +205 -202
- package/src/components/AppCompInputTextToFillDropdownNx.vue +341 -340
- package/src/components/AppCompInputTextToFillNx.vue +293 -313
- package/src/components/AppCompJauge.vue +81 -81
- package/src/components/AppCompMenu.vue +6 -1
- package/src/components/AppCompMenuItem.vue +246 -240
- package/src/components/AppCompNavigation.vue +977 -972
- package/src/components/AppCompNoteCall.vue +167 -161
- package/src/components/AppCompNoteCredit.vue +496 -491
- package/src/components/AppCompPlayBarNext.vue +2288 -2288
- package/src/components/AppCompPopUpNext.vue +508 -504
- package/src/components/AppCompQuizNext.vue +515 -510
- package/src/components/AppCompQuizRecall.vue +365 -350
- package/src/components/AppCompSVGNext.vue +346 -346
- package/src/components/AppCompSettingsMenu.vue +177 -172
- package/src/components/AppCompTableOfContent.vue +433 -427
- package/src/components/AppCompVideoPlayer.vue +378 -377
- package/src/components/AppCompViewDisplay.vue +6 -6
- package/src/components/BaseModule.vue +55 -55
- package/src/composables/useIdleDetector.js +56 -56
- package/src/composables/useQuiz.js +89 -89
- package/src/composables/useTimer.js +172 -172
- package/src/directives/nvdaFix.js +53 -53
- package/src/externalComps/ModuleView.vue +22 -22
- package/src/externalComps/SummaryView.vue +91 -91
- package/src/main.js +506 -476
- package/src/module/stores/appStore.js +960 -947
- package/src/module/xapi/ADL.js +520 -520
- package/src/module/xapi/Crypto/Hasher.js +241 -241
- package/src/module/xapi/Crypto/WordArray.js +278 -278
- package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
- package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
- package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
- package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
- package/src/module/xapi/Crypto/encoders/Base.js +105 -105
- package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
- package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
- package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
- package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
- package/src/module/xapi/Crypto/index.js +53 -53
- package/src/module/xapi/Statement/activity.js +47 -47
- package/src/module/xapi/Statement/agent.js +55 -55
- package/src/module/xapi/Statement/group.js +26 -26
- package/src/module/xapi/Statement/index.js +259 -259
- package/src/module/xapi/Statement/statement.js +253 -253
- package/src/module/xapi/Statement/statementRef.js +23 -23
- package/src/module/xapi/Statement/substatement.js +22 -22
- package/src/module/xapi/Statement/verb.js +36 -36
- package/src/module/xapi/activitytypes.js +17 -17
- package/src/module/xapi/launch.js +157 -157
- package/src/module/xapi/utils.js +167 -167
- package/src/module/xapi/verbs.js +294 -294
- package/src/module/xapi/wrapper.js +1895 -1895
- package/src/module/xapi/xapiStatement.js +444 -444
- package/src/plugins/analytics.js +34 -34
- package/src/plugins/bus.js +12 -8
- package/src/plugins/gsap.js +17 -17
- package/src/plugins/helper.js +355 -358
- package/src/plugins/i18n.js +29 -26
- package/src/plugins/idb.js +227 -227
- package/src/plugins/save.js +37 -37
- package/src/plugins/scorm.js +287 -287
- package/src/plugins/xapi.js +11 -11
- package/src/public/index.html +33 -33
- package/src/router/index.js +57 -57
- package/src/router/routes.js +312 -312
- package/src/shared/generalfuncs.js +344 -344
- package/src/shared/validators.js +1018 -1018
- package/tests/component/AppBaseButton.spec.js +53 -0
- package/tests/component/pinia.spec.js +24 -0
- package/{src/components/tests__ → tests/unit}/AppBaseButton.spec.js +53 -53
- package/tests/unit/AppCompAudio.spec.js +134 -0
- package/tests/unit/AppCompCarousel.spec.js +54 -0
- package/tests/unit/AppCompInputCheckBoxNx.spec.js +59 -0
- package/tests/unit/AppCompInputDropdownNx.spec.js +51 -0
- package/tests/unit/AppCompInputRadioNx.spec.js +59 -0
- package/tests/unit/AppCompInputTextNx.spec.js +44 -0
- package/tests/unit/AppCompInputTextTableNx.spec.js +77 -0
- package/tests/unit/AppCompInputTextToFillDropdownNx.spec.js +60 -0
- package/tests/unit/AppCompInputTextToFillNx.spec.js +45 -0
- package/tests/unit/AppCompNoteCredit.spec.js +58 -0
- package/tests/unit/AppCompQuizNext.spec.js +112 -0
- package/tests/unit/AppCompVideoPlayer.spec.js +169 -0
- package/tests/unit/useQuiz.spec.js +72 -0
- package/{src/components/tests__ → tests/unit}/useTimer.spec.js +91 -91
- package/vitest.config.js +42 -19
- package/vitest.setup.js +96 -0
- package/src/components/AppBaseButton.test.js +0 -21
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/experimental-ct-vue'
|
|
2
|
+
import AppBaseButton from '../../src/components/AppBaseButton.vue'
|
|
3
|
+
|
|
4
|
+
let component, btnElement
|
|
5
|
+
|
|
6
|
+
test.describe('AppBaseButton.vue', () => {
|
|
7
|
+
const btnText = 'Mon bouton custom'
|
|
8
|
+
const handleClick = async (payload) => {
|
|
9
|
+
console.log('👍Click Event - payload Received:', payload)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
test.beforeEach(async ({ mount, page }) => {
|
|
13
|
+
const onClick = test.info().attach('onClick', {}) // trace visible si besoin
|
|
14
|
+
component = await mount(AppBaseButton, {
|
|
15
|
+
props: { type: 'submit', isDisabled: true, onClick: handleClick },
|
|
16
|
+
slots: {
|
|
17
|
+
default: btnText
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
btnElement = await page.getByRole('button')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('It renders a button', async ({ page }) => {
|
|
25
|
+
await expect(btnElement).toBeVisible()
|
|
26
|
+
await expect(btnElement).toContainText(`${btnText}`)
|
|
27
|
+
})
|
|
28
|
+
//test prop value :type
|
|
29
|
+
test('Button has the correct type', async ({ page }) => {
|
|
30
|
+
await expect(btnElement).toHaveAttribute('type', 'submit')
|
|
31
|
+
})
|
|
32
|
+
// test prop value : isActive
|
|
33
|
+
test('Button render a correct state', async () => {
|
|
34
|
+
await expect(btnElement).toContainClass('md_disabled')
|
|
35
|
+
await expect(btnElement).toHaveAttribute('aria-disabled', 'true')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
//test click with event emitter
|
|
39
|
+
test('Emit event with value of the the $el when clicked', async ({mount, page}) => {
|
|
40
|
+
|
|
41
|
+
component = await mount(AppBaseButton, {
|
|
42
|
+
props: { type: 'submit', isDisabled: false, onClick: handleClick },
|
|
43
|
+
slots: { default: btnText }})
|
|
44
|
+
|
|
45
|
+
const btnElement = page.getByRole('button')
|
|
46
|
+
await expect(btnElement).toBeVisible()
|
|
47
|
+
//Using spy / mock to listen to event
|
|
48
|
+
|
|
49
|
+
await btnElement.click()
|
|
50
|
+
const elHandle = await btnElement.evaluate(el => el.outerHTML)
|
|
51
|
+
expect(elHandle).toContain('<button')
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// import { test, expect } from '@playwright/experimental-ct-vue'
|
|
2
|
+
// import { createPinia, setActivePinia } from 'pinia'
|
|
3
|
+
// import { useAppStore } from '../../src/module/stores/appStore.js'
|
|
4
|
+
// import Store from './Store.vue'
|
|
5
|
+
|
|
6
|
+
// test('override initialState', async ({ mount }) => {
|
|
7
|
+
// //create pinia instance
|
|
8
|
+
// const pinia = createPinia()
|
|
9
|
+
// setActivePinia(pinia)
|
|
10
|
+
|
|
11
|
+
// //create app store and set initial state
|
|
12
|
+
// const appStore = useAppStore()
|
|
13
|
+
// appStore.status = 'initialState'
|
|
14
|
+
|
|
15
|
+
// const component = await mount(Store, {
|
|
16
|
+
// hooksConfig: {
|
|
17
|
+
// store: { name: '$appStore' }
|
|
18
|
+
// },
|
|
19
|
+
// global: {
|
|
20
|
+
// plugins: [pinia]
|
|
21
|
+
// }
|
|
22
|
+
// })
|
|
23
|
+
// await expect(component).toContainText('initialState')
|
|
24
|
+
// })
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
import { mount } from '@vue/test-utils'
|
|
2
|
-
import AppBaseButton from '
|
|
3
|
-
import { describe, expect, test } from 'vitest'
|
|
4
|
-
|
|
5
|
-
describe('AppBaseButton.vue', () => {
|
|
6
|
-
test('It renders a button', () => {
|
|
7
|
-
const wrapper = mount(AppBaseButton)
|
|
8
|
-
|
|
9
|
-
expect(wrapper.text()).toContain('Button')
|
|
10
|
-
})
|
|
11
|
-
// test prop value :type
|
|
12
|
-
test('Button has the correct type', () => {
|
|
13
|
-
const wrapper = mount(AppBaseButton, {
|
|
14
|
-
props: { type: 'submit' }
|
|
15
|
-
})
|
|
16
|
-
// expect(wrapper.props().type).toBe(submit)
|
|
17
|
-
expect(wrapper.get('button').attributes('type')).toBe('submit')
|
|
18
|
-
})
|
|
19
|
-
//test prop value : isActive
|
|
20
|
-
test('Button render a correct state', () => {
|
|
21
|
-
const wrapper = mount(AppBaseButton, {
|
|
22
|
-
props: { isDisabled: true }
|
|
23
|
-
})
|
|
24
|
-
expect(wrapper.get('button').classes()).toEqual(
|
|
25
|
-
expect.arrayContaining(['md_disabled'])
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
// expect(wrapper.props().isActive).toBe(true)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
//test slot
|
|
32
|
-
test('Renders slot content properly', () => {
|
|
33
|
-
const wrapper = mount(AppBaseButton, {
|
|
34
|
-
slots: {
|
|
35
|
-
default: 'Mon bouton custome'
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
expect(wrapper.get('button').text()).toBe('Mon bouton custome')
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
//test click with event emitter
|
|
43
|
-
test('Emit event with value of the the $el when clicked', () => {
|
|
44
|
-
const wrapper = mount(AppBaseButton, {
|
|
45
|
-
slots: {
|
|
46
|
-
default: 'Mon bouton custome'
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
wrapper.get('button').trigger('click')
|
|
50
|
-
const clickEvent = wrapper.emitted('click')[0]
|
|
51
|
-
expect(clickEvent[0]).toEqual(wrapper.vm.$el)
|
|
52
|
-
})
|
|
53
|
-
})
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import AppBaseButton from '../../src/components/AppBaseButton.vue'
|
|
3
|
+
import { describe, expect, test } from 'vitest'
|
|
4
|
+
|
|
5
|
+
describe('AppBaseButton.vue', () => {
|
|
6
|
+
test('It renders a button', () => {
|
|
7
|
+
const wrapper = mount(AppBaseButton)
|
|
8
|
+
|
|
9
|
+
expect(wrapper.text()).toContain('Button')
|
|
10
|
+
})
|
|
11
|
+
// test prop value :type
|
|
12
|
+
test('Button has the correct type', () => {
|
|
13
|
+
const wrapper = mount(AppBaseButton, {
|
|
14
|
+
props: { type: 'submit' }
|
|
15
|
+
})
|
|
16
|
+
// expect(wrapper.props().type).toBe(submit)
|
|
17
|
+
expect(wrapper.get('button').attributes('type')).toBe('submit')
|
|
18
|
+
})
|
|
19
|
+
//test prop value : isActive
|
|
20
|
+
test('Button render a correct state', () => {
|
|
21
|
+
const wrapper = mount(AppBaseButton, {
|
|
22
|
+
props: { isDisabled: true }
|
|
23
|
+
})
|
|
24
|
+
expect(wrapper.get('button').classes()).toEqual(
|
|
25
|
+
expect.arrayContaining(['md_disabled'])
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
// expect(wrapper.props().isActive).toBe(true)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
//test slot
|
|
32
|
+
test('Renders slot content properly', () => {
|
|
33
|
+
const wrapper = mount(AppBaseButton, {
|
|
34
|
+
slots: {
|
|
35
|
+
default: 'Mon bouton custome'
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
expect(wrapper.get('button').text()).toBe('Mon bouton custome')
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
//test click with event emitter
|
|
43
|
+
test('Emit event with value of the the $el when clicked', () => {
|
|
44
|
+
const wrapper = mount(AppBaseButton, {
|
|
45
|
+
slots: {
|
|
46
|
+
default: 'Mon bouton custome'
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
wrapper.get('button').trigger('click')
|
|
50
|
+
const clickEvent = wrapper.emitted('click')[0]
|
|
51
|
+
expect(clickEvent[0]).toEqual(wrapper.vm.$el)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import { describe, it, test, expect } from 'vitest'
|
|
3
|
+
|
|
4
|
+
let dummyProps = {
|
|
5
|
+
id: 'P01',
|
|
6
|
+
activityRef: 'A03',
|
|
7
|
+
title: 'Lecteurs médias',
|
|
8
|
+
type: 'pg_normal',
|
|
9
|
+
audiosData: [
|
|
10
|
+
{
|
|
11
|
+
id: 'aud1',
|
|
12
|
+
mTitle: 'Et si... Annie Ernaux nous parlait',
|
|
13
|
+
mSources: [
|
|
14
|
+
{
|
|
15
|
+
type: 'mp3',
|
|
16
|
+
src: ' exemple_audio.mp3'
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
mPoster: 'audio_poster.png',
|
|
20
|
+
mAlt: "Portrait de l'autrice Annie Ernaux",
|
|
21
|
+
mTranscript:
|
|
22
|
+
'<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>'
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
import AppCompAudioPlayer from '@/components/AppCompAudio.vue'
|
|
28
|
+
import { validateAudioData } from '@/shared/validators.js'
|
|
29
|
+
|
|
30
|
+
describe('AppCompAudioPlayer', () => {
|
|
31
|
+
test('Validate received props', () => {
|
|
32
|
+
validateAudioData.mockReturnValue([])
|
|
33
|
+
const { audiosData } = dummyProps
|
|
34
|
+
mount(AppCompAudioPlayer, {
|
|
35
|
+
props: { audData: audiosData[0] }
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
expect(validateAudioData).toHaveBeenCalledWith({
|
|
39
|
+
id: 'aud1',
|
|
40
|
+
mTitle: 'Et si... Annie Ernaux nous parlait',
|
|
41
|
+
mSources: [
|
|
42
|
+
{
|
|
43
|
+
type: 'mp3',
|
|
44
|
+
src: ' exemple_audio.mp3'
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
mPoster: 'audio_poster.png',
|
|
48
|
+
mAlt: "Portrait de l'autrice Annie Ernaux",
|
|
49
|
+
mTranscript:
|
|
50
|
+
'<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>'
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('renders ErrorDisplay When validator returns errors', () => {
|
|
55
|
+
// simulate invalid props
|
|
56
|
+
validateAudioData.mockReturnValue([
|
|
57
|
+
'WARNING!>>> audio: 💥 Invalid declaration for audio element'
|
|
58
|
+
])
|
|
59
|
+
|
|
60
|
+
const wrapper = mount(AppCompAudioPlayer, {
|
|
61
|
+
props: { audData: { id: null } }
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
expect(
|
|
65
|
+
wrapper.findComponent({ name: 'AppBaseErrorDisplay' }).exists()
|
|
66
|
+
).toBe(true)
|
|
67
|
+
expect(wrapper.find('audio').exists()).toBe(false)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('It renders HTML audio Element', () => {
|
|
71
|
+
validateAudioData.mockReturnValue([]) // no Error
|
|
72
|
+
const wrapper = mount(AppCompAudioPlayer, {
|
|
73
|
+
props: { audData: { id: null } }
|
|
74
|
+
})
|
|
75
|
+
expect(
|
|
76
|
+
wrapper.findComponent({ name: 'AppBaseErrorDisplay' }).exists()
|
|
77
|
+
).toBe(false)
|
|
78
|
+
expect(wrapper.find('audio').exists()).toBe(true)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('audio Element has correct sources', async () => {
|
|
82
|
+
const { audiosData } = dummyProps
|
|
83
|
+
|
|
84
|
+
validateAudioData.mockReturnValue([]) // no Error
|
|
85
|
+
const wrapper = mount(AppCompAudioPlayer, {
|
|
86
|
+
props: { audData: audiosData[0] }
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
expect(wrapper.vm.mSources).toEqual(audiosData[0].mSources)
|
|
90
|
+
|
|
91
|
+
//sources are rendered in the DOM
|
|
92
|
+
await wrapper.vm.$nextTick()
|
|
93
|
+
const sources = wrapper.findAll('source')
|
|
94
|
+
expect(sources.length).toBe(1)
|
|
95
|
+
|
|
96
|
+
// --- 3) valider les valeurs réelles rendues ---
|
|
97
|
+
expect(sources[0].attributes().src).toBe(audiosData[0].mSources[0].src)
|
|
98
|
+
expect(sources[0].attributes().type).toBe('audio/mp3')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('computed $auElement returns correct data structure', async () => {
|
|
102
|
+
validateAudioData.mockReturnValue([])
|
|
103
|
+
const { audiosData } = dummyProps
|
|
104
|
+
const wrapper = mount(AppCompAudioPlayer, {
|
|
105
|
+
props: { audData: audiosData[0] }
|
|
106
|
+
})
|
|
107
|
+
// Simulate refs
|
|
108
|
+
const mockaudioRef = { tagName: 'audio' }
|
|
109
|
+
const mockContainerRef = { className: '__media-container' }
|
|
110
|
+
wrapper.vm.$refs['m-audio'] = mockaudioRef
|
|
111
|
+
wrapper.vm.$refs['$media-container'] = mockContainerRef
|
|
112
|
+
// Simulate refs isSet (audio ready) to true
|
|
113
|
+
wrapper.vm.isSet = true
|
|
114
|
+
await wrapper.vm.$nextTick()
|
|
115
|
+
// get audElement object
|
|
116
|
+
const obj = wrapper.vm.$audElement
|
|
117
|
+
const id = wrapper.vm.$props.audData.id
|
|
118
|
+
// expected data structure to be returned
|
|
119
|
+
const audElement = {
|
|
120
|
+
id,
|
|
121
|
+
mType: 'audio',
|
|
122
|
+
mElement: { localName: 'audio' },
|
|
123
|
+
mTranscript:
|
|
124
|
+
'<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>'
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
expect(obj.id).toEqual(audElement.id)
|
|
128
|
+
expect(obj.mType).toBe(audElement.mType)
|
|
129
|
+
expect(obj.mElement.tagName.toLowerCase()).toBe(
|
|
130
|
+
audElement.mElement.localName
|
|
131
|
+
)
|
|
132
|
+
expect(obj.mTranscript).toBe(audElement.mTranscript)
|
|
133
|
+
})
|
|
134
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import AppCompCarousel from '@/components/AppCompCarousel.vue'
|
|
3
|
+
import AppBaseButton from '@/components/AppBaseButton.vue'
|
|
4
|
+
import { beforeEach, describe, expect, it } from 'vitest'
|
|
5
|
+
|
|
6
|
+
const dummyProps = {
|
|
7
|
+
slides: [
|
|
8
|
+
{
|
|
9
|
+
imgSrc: 'https://loremflickr.com/500/500/kitten?random=1',
|
|
10
|
+
imgAlt: 'ceci est un chat',
|
|
11
|
+
title: 'Mon premier chat',
|
|
12
|
+
hypertext:
|
|
13
|
+
'<h3>Test</h3><p>Voici un texte de test pour le premier chat.</p>'
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
imgSrc: 'https://loremflickr.com/500/500/kitten?random=10',
|
|
17
|
+
imgAlt: 'ceci est un autre chat',
|
|
18
|
+
title: 'Le deuxième chat',
|
|
19
|
+
hypertext: ''
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
imgSrc: 'https://loremflickr.com/500/500/kitten?random=100',
|
|
23
|
+
imgAlt: 'ceci est un encore chat',
|
|
24
|
+
title: 'Le troisième chat',
|
|
25
|
+
hypertext: ''
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
name: 'Mon super carousel'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe('AppCompCarousel.vue', () => {
|
|
32
|
+
let wrapper = null
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
wrapper = mount(AppCompCarousel, {
|
|
35
|
+
props: dummyProps
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it(`displays the good amount of images`, () => {
|
|
40
|
+
expect(wrapper.findAll('img').length).toBe(dummyProps.slides.length)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('renders two appBaseButton components as controls', () => {
|
|
44
|
+
const btnComponents = wrapper.findAllComponents(AppBaseButton)
|
|
45
|
+
expect(btnComponents.length).toBe(2)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('updates the slide counter after nextSlide click', async () => {
|
|
49
|
+
const btnNext = wrapper.findAllComponents(AppBaseButton)[1]
|
|
50
|
+
await btnNext.trigger('click')
|
|
51
|
+
const counterTxt = wrapper.get('.carousel-index').text()
|
|
52
|
+
expect(counterTxt).toBe('2 / 3')
|
|
53
|
+
})
|
|
54
|
+
})
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import AppCompInputCheckBoxNx from '@/components/AppCompInputCheckBoxNx.vue'
|
|
3
|
+
import { beforeEach, describe, expect, test } from 'vitest'
|
|
4
|
+
|
|
5
|
+
const dummyProps = {
|
|
6
|
+
modelValue: ['cyan'],
|
|
7
|
+
inputData: [
|
|
8
|
+
{
|
|
9
|
+
id: '1',
|
|
10
|
+
value: 'rouge'
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: '2',
|
|
14
|
+
value: 'vert'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: '3',
|
|
18
|
+
value: 'bleu'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: '4',
|
|
22
|
+
value: 'jaune'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: '5',
|
|
26
|
+
value: 'magenta'
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: '6',
|
|
30
|
+
value: 'cyan'
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
solution: ['6'],
|
|
34
|
+
id: 'A02_P02_Q4'
|
|
35
|
+
}
|
|
36
|
+
describe('AppCompInputRadioNx.vue', () => {
|
|
37
|
+
let wrapper = null
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
wrapper = mount(AppCompInputCheckBoxNx, {
|
|
40
|
+
props: dummyProps
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
test(`renders a list of ${dummyProps.inputData.length} checkboxes`, () => {
|
|
44
|
+
expect(wrapper.findAll('input[type="checkbox"]').length).toBe(
|
|
45
|
+
dummyProps.inputData.length
|
|
46
|
+
)
|
|
47
|
+
})
|
|
48
|
+
test(`initially displays a single selected checkbox (checkbox #6 : cyan)`, () => {
|
|
49
|
+
const lastCheckbox = wrapper.findAll('input[type="checkbox"]')[5]
|
|
50
|
+
expect(lastCheckbox.attributes()).toHaveProperty('checked')
|
|
51
|
+
})
|
|
52
|
+
test('emits enable-submit and update:modelValue events on input change', async () => {
|
|
53
|
+
const boxes = wrapper.findAll('input[type="checkbox"]')
|
|
54
|
+
await boxes[0].setValue()
|
|
55
|
+
await boxes[4].setValue()
|
|
56
|
+
expect(wrapper.emitted()).toHaveProperty('enable-submit')
|
|
57
|
+
expect(wrapper.emitted()).toHaveProperty('update:modelValue')
|
|
58
|
+
})
|
|
59
|
+
})
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import AppCompInputDropdownNx from '@/components/AppCompInputDropdownNx.vue'
|
|
3
|
+
import { beforeEach, describe, expect, test } from 'vitest'
|
|
4
|
+
import { VSelect } from 'vuetify/components/VSelect'
|
|
5
|
+
|
|
6
|
+
const dummyProps = {
|
|
7
|
+
modelValue: ['Données primaires', 'Données secondaires'],
|
|
8
|
+
inputData: [
|
|
9
|
+
{
|
|
10
|
+
id: '0',
|
|
11
|
+
ennonce: 'Quelle sont les données?',
|
|
12
|
+
option: ['Données primaires', 'Données secondaires']
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: '1',
|
|
16
|
+
ennonce: 'Quelle sont les données?',
|
|
17
|
+
option: ['Données primaires', 'Données secondaires']
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
solution: ['Données primaires', 'Données secondaires'],
|
|
21
|
+
id: 'A02_P02_Q4'
|
|
22
|
+
}
|
|
23
|
+
describe('AppCompInputDropdownNx.vue', () => {
|
|
24
|
+
let wrapper = null
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
wrapper = mount(AppCompInputDropdownNx, {
|
|
27
|
+
props: dummyProps
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
test(`renders a list of vuetify v-select components`, () => {
|
|
31
|
+
expect(wrapper.findAllComponents(VSelect).length).toBe(
|
|
32
|
+
dummyProps.inputData.length
|
|
33
|
+
)
|
|
34
|
+
})
|
|
35
|
+
test(`displays the right labels`, () => {
|
|
36
|
+
const labels = wrapper.findAll('label')
|
|
37
|
+
labels.forEach((label, index) => {
|
|
38
|
+
expect(label.element.textContent).toBe(
|
|
39
|
+
dummyProps.inputData[index].ennonce
|
|
40
|
+
)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
test(`has the right initial data to display (modelValue prop)`, () => {
|
|
44
|
+
expect(wrapper.vm.inputsValue).toStrictEqual(dummyProps.modelValue)
|
|
45
|
+
})
|
|
46
|
+
test('emits enable-submit and update:modelValue events on input change', () => {
|
|
47
|
+
wrapper.vm.inputsValue = ['Données secondaires', 'Données primaires']
|
|
48
|
+
expect(wrapper.emitted()).toHaveProperty('enable-submit')
|
|
49
|
+
expect(wrapper.emitted()).toHaveProperty('update:modelValue')
|
|
50
|
+
})
|
|
51
|
+
})
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import AppCompInputRadioNx from '@/components/AppCompInputRadioNx.vue'
|
|
3
|
+
import { beforeEach, describe, expect, test } from 'vitest'
|
|
4
|
+
|
|
5
|
+
const dummyProps = {
|
|
6
|
+
modelValue: [{ id: '6', value: 'cyan', selected: true }],
|
|
7
|
+
inputData: [
|
|
8
|
+
{
|
|
9
|
+
id: '1',
|
|
10
|
+
value: 'rouge'
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: '2',
|
|
14
|
+
value:
|
|
15
|
+
'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: '3',
|
|
19
|
+
value: 'bleu'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: '4',
|
|
23
|
+
value: 'Une couleur'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: '5',
|
|
27
|
+
value: 'magenta'
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: '6',
|
|
31
|
+
value: 'cyan'
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
solution: ['4'],
|
|
35
|
+
id: 'A02_P02_Q4'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
describe('AppCompInputRadioNx.vue', () => {
|
|
39
|
+
let wrapper = null
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
wrapper = mount(AppCompInputRadioNx, {
|
|
42
|
+
props: dummyProps
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
test(`renders a list of ${dummyProps.inputData.length} radio buttons`, () => {
|
|
46
|
+
expect(wrapper.findAll('input[type="radio"]').length).toBe(
|
|
47
|
+
dummyProps.inputData.length
|
|
48
|
+
)
|
|
49
|
+
})
|
|
50
|
+
test(`has the id ${dummyProps.id}`, () => {
|
|
51
|
+
expect(wrapper.find('div').attributes('id')).toBe(`${dummyProps.id}`)
|
|
52
|
+
})
|
|
53
|
+
test('emits enable-submit and update:modelValue events on input change', async () => {
|
|
54
|
+
const radioBtn = wrapper.find('input[type="radio"]')
|
|
55
|
+
await radioBtn.setValue()
|
|
56
|
+
expect(wrapper.emitted()).toHaveProperty('enable-submit')
|
|
57
|
+
expect(wrapper.emitted()).toHaveProperty('update:modelValue')
|
|
58
|
+
})
|
|
59
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import AppCompInputTextNx from '@/components/AppCompInputTextNx.vue'
|
|
3
|
+
import { beforeEach, describe, expect, test } from 'vitest'
|
|
4
|
+
import { VTextarea } from 'vuetify/components/VTextarea'
|
|
5
|
+
|
|
6
|
+
const dummyProps = {
|
|
7
|
+
modelValue: ['Bonjour'],
|
|
8
|
+
inputData: null,
|
|
9
|
+
solution: null,
|
|
10
|
+
userAnswer: [],
|
|
11
|
+
id: 'A02_P02_Q4'
|
|
12
|
+
}
|
|
13
|
+
describe('AppCompInputTextNx.vue', () => {
|
|
14
|
+
let wrapper = null
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
wrapper = mount(AppCompInputTextNx, {
|
|
18
|
+
props: dummyProps
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
test('renders a vuetify textarea component', () => {
|
|
22
|
+
const textarea = wrapper.findComponent(VTextarea)
|
|
23
|
+
expect(textarea.exists()).toBe(true)
|
|
24
|
+
})
|
|
25
|
+
test('contains placeholder text "Écrivez ici."', () => {
|
|
26
|
+
const textarea = wrapper.find('textarea')
|
|
27
|
+
expect(textarea.attributes('placeholder')).toBe('Écrivez ici.')
|
|
28
|
+
})
|
|
29
|
+
test(`has the id textArea_${dummyProps.id}`, () => {
|
|
30
|
+
const textarea = wrapper.find('textarea')
|
|
31
|
+
expect(textarea.attributes('id')).toBe(`textArea_${dummyProps.id}`)
|
|
32
|
+
})
|
|
33
|
+
test('accepts some input text', async () => {
|
|
34
|
+
const textarea = wrapper.find('textarea')
|
|
35
|
+
await textarea.setValue('new value')
|
|
36
|
+
expect(textarea.element.value).toBe('new value')
|
|
37
|
+
})
|
|
38
|
+
test('emits enable-submit and update:modelValue events on input change', async () => {
|
|
39
|
+
const textarea = wrapper.find('textarea')
|
|
40
|
+
await textarea.setValue('new value')
|
|
41
|
+
expect(wrapper.emitted()).toHaveProperty('enable-submit')
|
|
42
|
+
expect(wrapper.emitted()).toHaveProperty('update:modelValue')
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import AppCompInputTextTableNx from '@/components/AppCompInputTextTableNx.vue'
|
|
3
|
+
import { beforeEach, describe, expect, test } from 'vitest'
|
|
4
|
+
import { VTextField } from 'vuetify/components/VTextField'
|
|
5
|
+
|
|
6
|
+
const dummyProps = {
|
|
7
|
+
modelValue: ['Blablabla', '1234', 'Lorem', 'Ipsum', 'cinq', '10'],
|
|
8
|
+
inputData: [
|
|
9
|
+
{
|
|
10
|
+
id: '0',
|
|
11
|
+
ennonce: 'le nombre « 1 »'
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: '1',
|
|
15
|
+
ennonce: 'le nombre « 2 »'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: '2',
|
|
19
|
+
ennonce: 'le nombre « 3 »'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: '3',
|
|
23
|
+
ennonce: 'le nombre « 4 »'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: '4',
|
|
27
|
+
ennonce: 'le nombre « 5 »'
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: '5',
|
|
31
|
+
ennonce: 'le nombre « 10 »'
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
solution: null,
|
|
35
|
+
id: 'A02_P02_Q4'
|
|
36
|
+
}
|
|
37
|
+
describe('AppCompInputTextTableNx.vue', () => {
|
|
38
|
+
let wrapper = null
|
|
39
|
+
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
wrapper = mount(AppCompInputTextTableNx, {
|
|
42
|
+
props: dummyProps
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
test(`renders a list of vuetify v-text-field`, () => {
|
|
46
|
+
const textfields = wrapper.findAllComponents(VTextField)
|
|
47
|
+
expect(textfields.length).toBe(dummyProps.inputData.length)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test(`displays a list of labels according to props received`, () => {
|
|
51
|
+
const labels = wrapper.findAll('label')
|
|
52
|
+
labels.forEach((label, index) => {
|
|
53
|
+
expect(label.element.textContent).toBe(
|
|
54
|
+
dummyProps.inputData[index].ennonce
|
|
55
|
+
)
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test(`displays the user saved answers`, () => {
|
|
60
|
+
const textfields = wrapper.findAll('input[type="text"]')
|
|
61
|
+
textfields.forEach((textfield, index) => {
|
|
62
|
+
expect(textfield.element.value).toBe(dummyProps.modelValue[index])
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
test('accepts some input text', async () => {
|
|
67
|
+
const textfield = wrapper.find('input[type="text"]')
|
|
68
|
+
await textfield.setValue('new value')
|
|
69
|
+
expect(textfield.element.value).toBe('new value')
|
|
70
|
+
})
|
|
71
|
+
test('emits enable-submit and update:modelValue events on input change', async () => {
|
|
72
|
+
const textfield = wrapper.find('input[type="text"]')
|
|
73
|
+
await textfield.setValue('new value')
|
|
74
|
+
expect(wrapper.emitted()).toHaveProperty('enable-submit')
|
|
75
|
+
expect(wrapper.emitted()).toHaveProperty('update:modelValue')
|
|
76
|
+
})
|
|
77
|
+
})
|