Дисклеймер

Это статья про «около ИТ» профессию, в которой используются «около нормальные» подходы и решения. Вы не найдёте здесь best practice, только кривые костыли. Пожалуйста, не берите ответы (когда они появятся) в продакшн: подумайте о своих пользователях!

Проблема

С одной стороны, мы в e-learning про развитие сотрудников, и нужно понимать всякие гуманитарные штуки. С другой, есть львиная доля задач по созданию контента, с продюсированием и прочим волшебством. И наконец, мы сидим около ИТ: там, где «почти фронтенд», «малая автоматизация», костыли и велосипеды. 

Бывают случаи, когда нужен очень своеобразный спец: чтобы мог собрать необычный курс без редактора, отдебажить то, что наделали всякие learning experience дизайнеры, договориться с вендорами по доработкам в LMS. Да такой, чтобы знал, как на низком уровне работают специфичные для нашего цеха инструменты, чтобы отличал Java от JavaScript, SCORM от SCRUM, xAPI от RESTfull API. Впрочем, будет достаточно, если он хотя бы был готов всему сам учиться.

И вот, припекло мне найти такого человека…

Что именно будем проверять

«Наш идеальный кандидат» не выживет без знания SCORM последней редакции. Это стандарт организации электронного контента. Его цель – производство курсов, которые работают одинаково в разных LMS (упростил как мог). Там три тома: один про упаковку и описание контента, второй про среду выполнения, третий про навигацию.

Где это нужно? Вот примеры типичных задачек (от простого к сложному):

  • Опубликовать PDF-документ в SCORM-compliant LMS, не используя дополнительное ПО.

  • Собрать курс в Tilda и опубликовать в LMS. Курс должен хранить прогресс пользователя в LMS.

  • Сделать сделать квиз со сложной системой подсчёта результатов на стороне клиента.

  • Сделать видео-плеер, который отправляет в LMS прогресс отдельно по каждому видео-файлу.

SCORM предполагает знание XML (для описания структуры контента) и JavaScript (для отправки данных из курсов в LMS). Причем опыт промышленной разработки на JS здесь не требуется, но умение работать с DOM, XHR и HTMLMediaElement очень нужны.

Поскольку в продакшене используется iSpring Suite (редактор для курсов), а его авторы и разработчики разных LMS по-разному интерпретируют SCORM, «будущий коллега» должен понимать, как эта штука работает на низком уровне, поскольку порой приходится делать твики на уровне кода уже после экспорта курса из редактора. К слову, так со всеми средствами разработки курсов.

Как проверяем

Вы уже догадались, что дальше будет несколько тестовых заданий разной сложности. Сразу отвечу на критику вроде: «Зачем всё это! Так не бывает. Спросите лучше что-нибудь общеупотребимое». Увы: так бывает, и все задачи не высосаны из пальца, но взяты из реальной жизни, и я ищу необычного специалиста. Конечно, собрать сет из всех кейсов сложно, но, если коллега решит 1/2 – это уже хороший результат.

Собственно задачи

Если это интересно, ответы можете оставлять в комментариях. Хейт тоже.

Задача 1

Что проверяем: знание SCORM RTE, JavaScript.

Сложность: ★☆☆

LMS с поддержкой SCORM 2004 4th edition. Вы делаете электронный курс, в который нужно вывести ФИО пользователя. Вызовете метод API_1484_11 для получения ФИО пользователя из LMS.

Ответ

Здесь всё просто. Метод GetValue возвращает значение переменной среды исполнения. ФИО хранится в переменной cmi.learner_name:

var name = API_1484_11.GetValue('cmi.learner_name');

Задача 2

Что проверяем: знание JavaScript.

Сложность: ★☆☆

Как из элемента iframe вызвать функцию в окне-родителе (в современном браузере)? Объясните, метод или напишите скрипт.

Ответ

Вызов функции из чужого окна напрямую может упереться в политику безопасности браузера. В общих чертах, решение предполагпает, что фрейм использует postMessage для отправки сообщения в окно родитель. Там, в свою очередь регистриуется обработчик события message, который в зависимости от свойства события data вызывает нужную функцию.

На хабре про это писали и не раз.

Задача 3

Что проверяем: знание SCORM CAM.

Сложность: ★☆☆

LMS с поддержкой SCORM 2004 4th edition. Вам нужно разместить там PDF-документ так, чтобы он открывался для просмотра в десктопных браузерах, а LMS получала информацию, что документ просмотрен при открытии. Как будут выглядеть секции organizations и resources в манифесте?

Ответ

Простое решение. Взять пример манифеста с официального сайта и подогнать под себя. Здесь важно, чтобы у элемента resource, к которому привязан документ, аттрибут adlcp:scormType был равен "asset", а не "sco". Иначе LMS, будет ждать от раздела курса инфо о завершении, но не дождётся:

<organizations default="default">
<organization identifier="default">
<title>Название документа</title>
<item isvisible="true" identifier="item00" identifierref="part00">
<title>Название документа</title>
</item>
</organization>
</organizations>

<resources>
<resource identifier="part00" adlcp:scormType="asset" type="webcontent" href="file.pdf">
<file href="file.pdf"/>
<resource>
</resources>

Задача 4

Что проверяем: знание HTMLMediaElement, видео-производство.

Сложность: ★☆☆

У вас есть видеокурс с одним 10-минутным видео на 4Гб. Пользователи жалуются, что видео бесконечно долго загружается. Вы уже проверили Network в DevTools: код ответа 206. Что можно сделать с видео, чтобы нормально работало?

Ответ
  1. Разбить видео на фрагменты поменьше (если контент позволяет).

  2. Изменить разметку страницы: для элемента video установить атрибут preload="metadata".

  3. Перекодировать видео, так чтобы уменьшить битрейт (и объем) и перенести мета-данные в начало видео. Например используя утилиту ffmpeg:

    ffmpeg -i input.mp4 -c:v libx264 -c:a copy -preset veryslow -crf 22 -movflags +faststart output.mp4

Задача 5

Что проверяем: знание SCORM RTE, iSpring Suite.

Сложность: ★★☆

Вы создали курс в iSpring Suite. В нём один единственный слайд с тестом. Курс оценивается и считается завершенным при успешном прохождении теста. Укажите, какие значения принимают переменные SCORM RTE на каждом из этапов работы пользователя с курсом. Опишите возможные проблемы.

Этап

Переменная

Значение

Пользователь первый раз открыл курс

cmi.progress_measure

 

cmi.completion_status

 

cmi.success_status

 

Пользователь прошел тест

cmi.progress_measure

 

cmi.completion_status

 

cmi.success_status

 

Ответ

Проблема в том, что в iSpring отправляет cmi.completion_status = "completed", когда просмотрены все слайды. Если LMS при завершении курса ориентируется на cmi.completion_status, то курс будет завершен сразу при первом открытии (слайд-то один), вне зависимости от результатов теста. Чтобы этого избежать в LMS нужно настроить завершение данного курса по cmi.success_status и, желательно, поправить код в файле lms.js курса, убрав отправку прогресса и скорректировав условия отправки cmi.completion_status.

Этап

Переменная

Значение

Пользователь первый раз открыл курс

cmi.progress_measure

 100

cmi.completion_status

 "completed"

cmi.success_status

 "unknown"

Пользователь прошел тест

cmi.progress_measure

 100

cmi.completion_status

 "completed"

cmi.success_status

 "passed"

Задача 6

Что проверяем: знание SCORM CAM, JavaScript.

Сложность: ★★☆

Как оценить, какой объём занимает курс, упакованный по стандарту SCORM 2004 4th edition и загруженный в LMS, не имея доступа к серверной части (используя только веб-браузер).

Ответ

Позвонить инженерам. Если они не берут трубку, то использовать план Б.

Курс SCORM 2004 4th edition обязательно включает в себя файл imsmanifest.xml – манифест. В манифесте по стандарту должны быть перечислены все файлы курса с url. Значит, план Б такой:

  1. Открываем курс как пользователь.

  2. Получаем из манифеста url всех файлов (url манифеста определяется по url открытой страницы).

  3. Отправляем HTTP-запросы с url каждого файла. Чтобы не загружать тело ответа используем метод HEAD.

  4. Суммируем Content-Length ответов и получаем размер курса в байтах.

Задача 7

Что проверяем: знание SCORM SN, JavaScript.

Сложность: ★★☆

Посмотрите на фрагмент манифеста из курса в SCORM 2004 4th edition.

<organization identifier="default">
	<title>Выучи Go за 15 минут</title>
  <item isvisible="true" identifier="item00" identifierref="part00">
  	<title>Введение</title>
   </item>
   <item isvisible="true" identifier="item01" identifierref="part01">
   	<title>Заключение</title>
   </item>
</organization>

Напишите функцию, которая «перенесёт» пользователя из раздела «Введение» в раздел «Заключение». Алгоритм поиска API_1484_11 писать не нужно.

Ответ

С помощью GetValue('adl.nav.request_valid.choice.{target=item01}') проверяем, существует ли раздел курса с id "item01". Затем записываем его в 'adl.nav.request' и коммитим. После вызова метода Terminate, LMS должна открыть нужный раздел:

function goToLastItem() {
if (API_1484_11.GetValue('adl.nav.request_valid.choice.{target=item01}')) {
API_1484_11.SetValue ('adl.nav.request', '{target=item01}choice');
API_1484_11.Commit();
API_1484_11.Terminate();
}
}

Задача 8

Что проверяем: знание SCORM RTE, JavaScript, iSpring Suite.

Сложность: ★★★

LMS с поддержкой SCORM 2004 4th edition. Вы разработали тест в iSpring Suite. Есть проблема: кириллица в ответах пользователей не сохраняется в LMS. Например, «Ответ» сохраняется как «0______». Заказчик говорит, что видеть ответы – «критичное для бизнеса требование». Что можно сделать в этой ситуации? Предложите алгоритм или напишите скрипт.

Ответ

Это извращение, сразу предупреждаю. Можно было бы попробовать поправить что-то внутри lms.js внутри SCORM-пакета, но копаться в обфусцированном коде - дело неблагодарное. Лучший вариант, написать квиз с нуля на JS. Если критично использовать именно это авторское средство, то порядок действий такой:

  1. В настройках теста активировать отправку результатов на сервер.

  2. Указать фиктивный адрес сервера (например, localhost).

  3. Написать скрипт, который перехватывает запрос к этому серверу, достаёт из него ответы и отправляет отправляет в LMS через SCORM API:

    1. Проксируем методы XMLHttpRequest.open и XMLHttpRequest.send, так, чтобы при отправке запроса на фиктивный адрес он перехватывался и парсился.

    2. Парсим http-запрос, достаём кириллицу.

    3. Ищем API_1484_11.

    4. Для каждого отвеченного вопроса создаём новый cmi.interactions.n через API_1484_11.SetValue.

    5. Сохраняем всё API_1484_11.Commit();

Кому интересна реализация, пишите в личку.

Задача 9

Что проверяем: знание SCORM RTE, JavaScript, iSpring Suite.

Сложность: ★★★

Вам прислали курс в iSpring Suite. В нём 100500 слайдов и закрытая навигация. Вам нужно проверить на тестовом стенде, как работает слайд №100499 в разных браузерах. Изолированно от курса слайд тестировать нельзя, т.к. он содержит ссылки на другие слайды курса. Добавлять элементы навигации нельзя. Менять режим навигации нельзя. Через 5 минут нужно дать ответ разработчику: можно ли публиковать курс на продуктив. Как быстро перейти к нужному слайду, не внося изменения в курс?

Ответ

На странице есть HTML-элемент, который сам iSpring использует для переключения слайдов. Точнее, не сам элемент, а объект, возвращаемый методом getCore этого элемента. Проблема в том, что идентификатор у этого "пульта от курса" каждый раз новый. Хорошая новость в том, что начало у айдишника всегда одно - "core". Т.е. этот элемент можно получить по CSS-селектору [id^="core"]. Поэтому, чтобы быстро попасть к нужному слайду, нужно сделать так (нумерация слайдов начинается с нуля):

  1. Открыть курс.

  2. Открыть DevTools (Shift+Ctrl+I или F12, стыдно не знать).

  3. С помощью инспектора элементов выбрать окно с курсом.

  4. Ввести в консоли: document.querySelector('[id^="core"]').getCore().gotoSlide(100498,document.body);
    Чёрт знает, как используется второй аргумент gotoSlide, до 9й версии его не было. Практика показывает, что можно подсунуть любой элемент страницы.

  5. При желании, можно сделать себе букмарклет для переключения слайдов.

Комментарии (0)