The purpose of this document is to describe how to create, change and test entry points in FarmData2.
Entry points are pages that provide FarmData2 functionality. The entry points are accessed through the FarmData2 menus (FarmData2, FD2 Examples, FD2 School) that appear in farmOS. For example, the Tray Seeding, Direct Seeding and Transplanting menu options lead to pages (entry points) for collecting data about the corresponding activity.
Familiarity with the Quick Tour of FarmData2 and the Overview of the FarmData2 Codebase will be helpful in reading this document.
- Creating a New Entry Point
- Tour of an Entry Point
New entry points in FarmData2 are created by customizing an entry point template. The entry point template defines the basic structure for an entry point and provides a small set of functionality. It serves as a starting point for creating new entry points and helps to maintain some structural consistency across entry points.
A running instance of an entry point template can be found by choosing the "Example Entry Point" option in the FD2 Examples menu in the FarmData2 Development Environment. The running entry point template looks as follows:
The "Submit" button provided does not submit any data to the farmOS server. Implementing that functionality is part of the customization process.
When you want to add a new entry point to FarmData2, the following command will generate a new entry point from the entry point template as a starting point for you:
addEntrypoint.bashThis command will prompt you for the following information that will be used to create the new entry point:
- The module in which to create the new entry point. The entry point can be created in the
farm_fd2,farm_fd2_examples, orfarm_fd2_schoolmodule, which correspond to the similarly named FarmData2 menus in farmOS. - The name for the new entry point. This name is used internally in code and is not visible to users. The name should be entered in
snake_case, with words being all lowercase and separated by underscore (_) characters. - A short title for the new entry point. The title is the text that will be used as the menu option for accessing the entry point. It also appears at the top of the entry point page. The title should be in Title Case, with words capitalized and separated by spaces. This often uses the same words as the name.
- A one sentence description of the new entry point. This description is used as a tooltip by Drupal and should be written to be meaningful to a user.
- The parent menu on which the option for this entry point should be added. The title for this entry point will appear on the specified menu.
- The permissions that a user must have to see the menu. The permissions that are available can be found by logging into farmOS as
adminand visiting the farmOS People page. Then use the browser dev-tools to inspect the check boxes to find the name of the permission.
After confirming the information that you entered, the script will generate the new entry point from the template by:
- Creating and switching to a new feature branch named
add_<entry_point_name>_entry_point - Creating a subdirectory in the module containing the new entry point.
- Customizing the entry point template files with the information you entered and copying them into the subdirectory.
- Updating the module's configuration so that the menu option for the new entry point will appear in farmOS.
- Running tests to confirm that the new entry point was created.
- Committing the customized entry point files to the feature branch.
This process typically takes several minutes.
The addEntrypoint.bash flags section provides some more information about the script.
The running instance of the new entry point can be found in farmOS and the source code for it can be found in your FarmData2 repository.
Open Mozilla Firefox and login to farmOS at http://farmos. Then use the FarmData2 menus to find the module containing the new entry point that you created. If the entrypoint page is blank when you visit it the first time, hold the "shift" key and click the reload button in the browser (⟳).
The directory for the module in which the new entry point is being created will contain a subdirectory for the new entry point's code.
For example, the subdirectory containing the source code for the example_entry_point in the farm_fd2_examples is shown in the following directory tree:
FarmData2 ├── ... ├── modules │ ├── css │ ├── farm_fd2 │ │ └── ... │ ├── farm_fd2_examples │ │ ├── dist │ │ ├── src │ │ | ├── entrypoints │ │ | │ ├── ... │ │ | │ ├── component_examples │ │ | │ ├── date_selector │ │ | │ ├── example_entry_point │ │ | │ └── ... | | | ├── module | | | └── public │ │ └── vite.config.js │ └── farm_fd2_school │ └── ... :
The functionality of the entry point template is customized to its intended purpose by adding components to the page in the App.vue file and implementing the submitForm function in the lib.js file. Each of these files contain comments that describe how to customize the entry point.
The Tour of an Entry Point section provides more detail and examples of how to customize the entry point template.
When the source code associated with an entry point is changed, the module containing it needs to be rebuilt for the changes to appear in farmOS.
Most commonly you will want to watch the module containing the entry point on which you are working. Watching the module causes it to be rebuilt any time changes are made to any of the source files that it uses. To watch a module, open a new terminal and use the command for the module containing the entry point on which you are working:
npm run watch:fd2npm run watch:examplesnpm run watch:school
When changes to the source files are saved, output in the terminal will show the module being rebuilt and will report any errors that occur.
The Watch Alternatives section describes other approaches to watching or building modules that might be useful or preferred in some circumstances.
New entry points are populated with unit tests and end-to-end tests from the template. These tests check the functionality provided by the template.
They will need to be changed and more tests will need be added as the functionality of the entry point is customized. Entry Point Test Files section describes the conventions that are used for these tests.
To run the unit tests for an entry point open a new terminal and adapt the following command:
test.bash --unit --<module> --glob=modules/**/<entry_point_name>/*.unit.cy.js --gui
<module>must be one offd2,examplesorschool.<entry_point_name>must be the name of the entry point to test.- The
--guiflag causes the tests to run in the Cypress GUI. Omit the--guiflag to run the tests headless with results reported in the terminal. - Omit the
--globflag to run the unit tests for all entry points in the module.
To run the end-to-end (e2e) tests for an entry point open a new terminal and adapt the following command:
test.bash --e2e --live --<module> --glob=modules/**/<entry_point_name>/*.e2e.cy.js --gui
<module>must be one offd2,examplesorschool.<entry_point_name>must be the name of the entry point to test.- The
--guiflag causes the tests to run in the Cypress GUI. Omit the--guiflag to run the tests headless with results reported in the terminal. - Omit the
--globflag to run the e2e tests for all entry points in the module.
The Example Entry Point contained on the FD2 Examples menu is an example of a new entry point as created by the addEntrypoint.bash script. The following sub-sections provide a guide to the structure and functionality of the example entry point. They also provide pointers to more information and links to implemented entry points that will be helpful in customizing new entry points.
When the addEntryPoint.bash script creates a new entry point to a module, it adds a subdirectory for the new entry point to the module. It populates this subdirectory with template files as a starting point for the new entry point. For example, the subdirectory for the example_entry_point is shown in the following directory tree:
FarmData2 ├── modules │ ├── ... │ ├── farm_f2 │ ├── farm_fd2_examples │ │ ├── dist │ │ ├── src │ │ | ├── entrypoints │ │ | │ ├── ... │ │ | │ ├── example_entry_point │ │ | │ │ ├── App.vue │ │ | │ │ ├── example_entry_point.comment.e2e.cy.js │ │ | │ | ├── example_entry_point.date.e2e.cy.js │ │ | │ | ├── example_entry_point.exists.e2e.cy.js │ │ | │ | ├── example_entry_point.html │ │ | │ | ├── example_entry_point.js │ │ | │ | ├── example_entry_point.submission.e2e.cy.js │ │ | │ | ├── example_entry_point.submitReset.e2e.cy.js │ │ | │ | ├── index.html │ │ | │ | ├── lib.js │ │ | │ | ├── lib.submit.unit.cy.js │ │ | │ | └── lib.submitError.unit.cy.js │ │ | │ └── ... | | | ├── module | | | └── public │ │ └── vite.config.js │ └── farm_f2_school :
- The
App.vueandlib.jsfiles contain the code that implements the entry point.App.vuedefines the Vue application for the entry point.lib.jscontains thesubmitFormfunction that creates the data records for the entry point in the farmOS database.
- The files that end in
.cy.jscontain tests for the entry point.- The files that end in
.e2e.cy.jscontain end-to-end tests for the entry point. - The
lib.*.unit.cy.jsfiles contain unit tests for thesubmitFormfunction inlib.js.
- The files that end in
- The
index.html,example_entry_point.html, andexample_entry_point.jsare boilerplate for the Vue app and will not need to be edited.
More details on these files and how to customize them for your entry point can be found in the following sub-sections:
The following sub-sections provide a guide to the example_entry_point and pointers to more information and fully implemented entry points that will served as helpful examples in customizing new entry points. You can follow along by looking at the example_entry_point in the farm_fd2_examples module, or by having created a new entry point of your own by using the addEntryPoint.bash script.
The App.vue file defines a Vue Single File Component (SFC) using the Vue's Options API. This SFC is what is displayed when the entry point is visited in farmOS.
If you are not familiar with Vue SFC or Vue's Options API the following resources are great places to start:
- The "Getting Started" and "Essentials" sections of the Vue Introduction.
- Vue Mastery's Intro to Vue 3 video course are a great place to start.
Vue Components are added to an entry point's App.vue file to customize its input form to its purpose. The following resources will be helpful in customizing the entry point's App.vue file:
App.vuein the Example Entry Point contains comments explaining its structure and operation, and to guide its customization for new entry points.- The "Component Basics" section of the Vue Introduction shows how to add Vue component to a SFC.
- The FarmData2 Documentation page provides a links to the documentation for each custom FarmData2 Vue component, a live running example of the component, and a static code example of its use.
- The guide to Working on a Vue.js Component provides information about creating and testing custom Vue Components for FarmData2.
- The documentation for the BootstrapVueNext Components. These Vue Components are typically used inside of the custom Vue Components for FarmData2, but might be used directly in an entry point. Note that BootstrapVueNext is under active development and its documentation is evolving with its development. FarmData2 has pinned to a specific version of BootstrapVueNext for stability. There will be inconsistencies between the BootstrapVueNext documentation and the code in FarmData2.
Examples of App.vue files can be found in the existing entry points including:
App.vuein the Tray Seeding entry point contains extra documentation to help it serve as an example.App.vuefiles can also be found in other entry points.
The lib.js file is a JavaScript library for the entry point. It contains at least the submitForm function, which is called when the "Submit" button is clicked. It can also contain other functions that are useful for the entrypoint.
Implementing the submitForm and other functions in the lib.js file, as opposed to directly in the App.vue file, makes it possible to unit test them. See the Entry Point Unit Tests section for more details.
When the "Submit" button on a entry point page is clicked, the submitForm function in the lib.js file is called and the data entered into the form is passed to it as an argument. This function must be customized to its entry point's purpose by using the farmosUtil library to create the farmOS assets, logs and quantities needed to represent the entry point's operation.
The following resources will be helpful in customizing the entry point's submitForm function:
lib.jsin the Example Entry Point contains a TODO list and comments that describe the customizations that need to be made.- The
farmOSUtillibrary contains methods for creating the farmOS assets, logs and quantities needed to represent the entry point's operation.- The Guide to working on a Library provides information about extending the
farmosUtillibrary to include new functions.
- The Guide to working on a Library provides information about extending the
Examples of lib.js files can be found in the existing entry points including:
- 'lib.js in the Tray Seeding entry point, which contains extra documentation to help it serve as an example.
lib.jsfiles can also be found in other entry points.
Entry points have two types of tests associated with them. The functions in the lib.js file have unit tests and the functionality in the App.vue file has end-to-end tests.
The template files for a new entry point include two unit test files that will need to be customized for your entry point:
lib.submit.unit.cy.js- tests successful calls to thesubmitFormfunction inlib.js.lib.submitError.unit.cy.jstests unsuccessful calls to thesubmitFormfunction in thelib.jsfile.
If other functions are added to the lib.js file, their unit tests should be placed in a file incorporating their name. For example, if a function named computeValid is added then its unit tests should be placed in lib.computeValid.unit.cy.js.
You can find examples of the unit tests for the submitForm function in other entry points including:
lib.submit.unit.cy.jsandlib.submitError.unit.cy.jsin the Tray Seeding entry point, which contain extra comments to serve as an example.- Similar unit test files can also be found in other entry points.
The entry point end-to-end tests check that the entry point exists, its components are correct, and that the form passes the correct data to the submitForm function.
The templates for new entry points provides the following end-to-end (e2e) tests that will need to be expanded and customized for new entry points:
example_entry_point.exists.e2e.cy.js- tests that the page exists, can be accessed by appropriate users, and contains the main structural elements of an entry point.- One test file for each component on the page:
example_entry_point.date.e2e.cy.js- tests theDateSelectorcomponent.example_entry_point.comment.e2e.cy.js- tests theCommentBoxcomponent.
example_entry_point.submission.e2e.cy.js- tests that the correct data is passed to thesubmitFormfunction.example_entry_point.submitReset.e2e.cy.js- tests theSubmitResetButtonscomponent.
You can find examples of the e2e tests in other entry points including:
tray_seeding.*.e2e.cy.jsin the Tray Seeding entry point, which contain extra comments to serve as an example.- Similar e2e test files can also be found in other entry points.
The Tips for Testing in FarmData2 document provides some more general testing tips that might also be helpful.
Flags can be used with the addEntrypoint.bash script to change its behavior.
-
The
--devflag causes theaddEntrypoint.bashscript to create its new feature branch from the current branch instead of from thedevelopmentbranch. This makes it easier to test changes that are being made to the template files. -
Other flags may be added in the future.
The module and public directories in each of the FarmData2 modules contains the files needed to build the associated Drupal module that plugs into farmOS.
Typically, these files will not need to be modified manually. The addEntrypoint.bash script will automatically add the information for the new entry point to the appropriate module files. If you find yourself manually editing these files, check with one of the project maintainers on the FarmData2 Zulip Chat. They can confirm that is the appropriate approach for what you are trying to do.
Watching a Module rebuilds the module when files change so that the changes appear in the live farmOS instance.
FarmData2 provides several other ways that modules can be watched, built, and tested.
The modules can be built manually with the following commands:
npm run build:fd2npm run build:examplesnpm run build:school
Two servers enable the Vue applications in each of the FarmData2 modules to be viewed and tested outside of the live farmOS instance.
The dev server serves dynamically built versions of the Vue application in a FarmData2 modules. It also watches the files in the module for changes and dynamically updates the app that is running in the browser.
The dev server can be started for a module with the following commands:
npm run dev:fd2npm run dev:examplesnpm run dev:school
With the dev server running, a module's entry points can be accessed in the browser by adapting the following URL:
http://localhost:5173/fd2/< entry point name >
For example, to access the Tray Seeding entry point run the dev server for the fd2 module and adapt the following URL:
http://localhost:5173/fd2/tray_seeding
The end-to-end tests for a module can also be run by using the dev server instead of the live server by adapting the following command:
test.bash --e2e --dev --<module> --glob=modules/**/<entry_point_name>/*.e2e.cy.js --gui
The preview server serves statically built versions of the Vue application in a FarmData2 modules.
npm run preview:fd2npm run preview:examplesnpm run preview:school
With the preview server running, a module's entry points can be accessed in the browser by adapting the following URL:
http://localhost:4173/fd2/<entry_point_name>
For example, to access the Tray Seeding entry point run the preview server for the fd2 module and adapt the following URL:
http://localhost:4173/fd2/tray_seeding
The end-to-end tests for a module can also be run by using the preview server instead of the live server by adapting the following command:
test.bash --e2e --preview --<module> --glob=modules/**/<entry_point_name>/*.e2e.cy.js --gui
